[cfe-commits] r81870 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp test/SemaCXX/conversion-delete-expr.cpp test/SemaCXX/new-delete.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Sep 15 10:21:47 PDT 2009
Author: fjahanian
Date: Tue Sep 15 12:21:47 2009
New Revision: 81870
URL: http://llvm.org/viewvc/llvm-project?rev=81870&view=rev
Log:
Perform overload resolution when selecting a pointer conversion
function for delete of a class expression and issue
good diagnostic when result is ambiguous.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp
cfe/trunk/test/SemaCXX/new-delete.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81870&r1=81869&r2=81870&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 15 12:21:47 2009
@@ -1558,6 +1558,8 @@
def err_new_uninitialized_const : Error<
"must provide an initializer if the allocated object is 'const'">;
def err_delete_operand : Error<"cannot delete expression of type %0">;
+def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
+ "expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behaviour">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81870&r1=81869&r2=81870&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Sep 15 12:21:47 2009
@@ -736,6 +736,7 @@
QualType Type = Ex->getType();
if (const RecordType *Record = Type->getAs<RecordType>()) {
+ OverloadCandidateSet CandidateSet;
llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
OverloadedFunctionDecl *Conversions =
@@ -754,20 +755,32 @@
QualType ConvType = Conv->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
if (ConvPtrType->getPointeeType()->isObjectType())
- ObjectPtrConversions.push_back(Conv);
+ AddConversionCandidate(Conv, Ex, ConvType, CandidateSet);
}
-
- if (ObjectPtrConversions.size() == 1) {
- // We have a single conversion to a pointer-to-object type. Perform
- // that conversion.
- Operand.release();
- if (PerformImplicitConversion(Ex,
- ObjectPtrConversions.front()->getConversionType(),
- "converting"))
+ OverloadCandidateSet::iterator Best;
+ switch (BestViableFunction(CandidateSet, Ex->getLocStart(), Best)) {
+ case OR_Success:
+ {
+ Operand.release();
+ CXXConversionDecl *Conversion
+ = cast<CXXConversionDecl>(Best->Function);
+ if (PerformImplicitConversion(Ex,
+ Conversion->getConversionType(),
+ "converting"))
+ return ExprError();
+
+ Operand = Owned(Ex);
+ Type = Ex->getType();
+ break;
+ }
+ case OR_No_Viable_Function:
+ case OR_Deleted:
+ break; // Will issue error below.
+ case OR_Ambiguous:
+ Diag(StartLoc, diag::err_ambiguous_delete_operand)
+ << Type << Ex->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
return ExprError();
-
- Operand = Owned(Ex);
- Type = Ex->getType();
}
}
Modified: cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp?rev=81870&r1=81869&r2=81870&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp Tue Sep 15 12:21:47 2009
@@ -2,16 +2,16 @@
// Test1
struct B {
- operator char *();
+ operator char *(); // expected-note {{candidate function}}
};
struct D : B {
- operator int *();
+ operator int *(); // expected-note {{candidate function}}
};
void f (D d)
{
- delete d; // expected-error {{cannot delete expression of type 'struct D'}}
+ delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D' to a pointer}}
}
// Test2
@@ -30,25 +30,25 @@
// Test3
struct B2 {
- operator const int *();
+ operator const int *(); // expected-note {{candidate function}}
};
struct D2 : B2 {
- operator int *();
+ operator int *(); // expected-note {{candidate function}}
};
void f2 (D2 d)
{
- delete d; // expected-error {{cannot delete expression of type 'struct D2'}}
+ delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D2' to a pointer}}
}
// Test4
struct B3 {
- operator const int *();
+ operator const int *(); // expected-note {{candidate function}}
};
struct A3 {
- operator const int *();
+ operator const int *(); // expected-note {{candidate function}}
};
struct D3 : A3, B3 {
@@ -56,7 +56,7 @@
void f3 (D3 d)
{
- delete d; // expected-error {{cannot delete expression of type 'struct D3'}}
+ delete d; // expected-error {{mbiguous conversion of delete expression of type 'struct D3' to a pointer}}
}
// Test5
@@ -78,16 +78,19 @@
// Test7
struct Base {
- operator int*();
+ operator int*(); // expected-note {{candidate function}}
};
struct Derived : Base {
- operator int*() const; // not the same function as Base's non-const operator int()
+ // not the same function as Base's non-const operator int()
+ operator int*() const; // expected-note {{candidate function}}
};
-void foo6(const Derived cd) {
- // FIXME. overload resolution must select Derived::operator int*() const;
- delete cd; // expected-error {{cannot delete expression of type 'struct Derived const'}}
+void foo6(const Derived cd, Derived d) {
+ // overload resolution selects Derived::operator int*() const;
+ delete cd;
+
+ delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct Derived' to a pointer}}
}
// Test8
@@ -105,7 +108,3 @@
// OK. In selecting a conversion to pointer function, template convesions are skipped.
delete d;
}
-
-
-
-
Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=81870&r1=81869&r2=81870&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Tue Sep 15 12:21:47 2009
@@ -104,12 +104,12 @@
};
struct X2 {
- operator int*();
- operator float*();
+ operator int*(); // expected-note {{candidate function}}
+ operator float*(); // expected-note {{candidate function}}
};
void test_delete_conv(X0 x0, X1 x1, X2 x2) {
delete x0; // expected-error{{cannot delete}}
delete x1;
- delete x2; // expected-error{{cannot delete}}
-}
\ No newline at end of file
+ delete x2; // expected-error{{ambiguous conversion of delete expression of type 'struct X2' to a pointer}}
+}
More information about the cfe-commits
mailing list