[cfe-commits] r81898 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/deleted-function.cpp test/SemaCXX/direct-initializer.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Sep 15 12:12:21 PDT 2009
Author: fjahanian
Date: Tue Sep 15 14:12:21 2009
New Revision: 81898
URL: http://llvm.org/viewvc/llvm-project?rev=81898&view=rev
Log:
Issue good diagnostics when initialization failes due to
ambiguity in type conversion function selection.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/deleted-function.cpp
cfe/trunk/test/SemaCXX/direct-initializer.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81898&r1=81897&r2=81898&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 15 14:12:21 2009
@@ -1643,6 +1643,8 @@
// FIXME: %2 is an english string here.
def err_typecheck_convert_incompatible : Error<
"incompatible type %2 %1, expected %0">;
+def err_typecheck_convert_ambiguous : Error<
+ "ambiguity in initializing value of type %0 with initializer of type %1">;
def err_cannot_initialize_decl_noname : Error<
"cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
"of type %2">;
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=81898&r1=81897&r2=81898&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Sep 15 14:12:21 2009
@@ -734,6 +734,15 @@
return NULL;
}
+ /// OverloadingResult - Capture the result of performing overload
+ /// resolution.
+ enum OverloadingResult {
+ OR_Success, ///< Overload resolution succeeded.
+ OR_No_Viable_Function, ///< No viable function found.
+ OR_Ambiguous, ///< Ambiguous candidates found.
+ OR_Deleted ///< Overload resoltuion refers to a deleted function.
+ };
+
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T);
@@ -770,7 +779,7 @@
bool CheckMemberPointerConversion(Expr *From, QualType ToType,
CastExpr::CastKind &Kind);
bool IsQualificationConversion(QualType FromType, QualType ToType);
- bool IsUserDefinedConversion(Expr *From, QualType ToType,
+ OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
OverloadCandidateSet& Conversions,
bool AllowConversionFunctions,
@@ -808,15 +817,6 @@
bool PerformObjectMemberConversion(Expr *&From, NamedDecl *Member);
- /// OverloadingResult - Capture the result of performing overload
- /// resolution.
- enum OverloadingResult {
- OR_Success, ///< Overload resolution succeeded.
- OR_No_Viable_Function, ///< No viable function found.
- OR_Ambiguous, ///< Ambiguous candidates found.
- OR_Deleted ///< Overload resoltuion refers to a deleted function.
- };
-
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
// TODO: make this is a typesafe union.
typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet;
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=81898&r1=81897&r2=81898&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Sep 15 14:12:21 2009
@@ -70,11 +70,23 @@
if (S.getLangOptions().CPlusPlus) {
// FIXME: I dislike this error message. A lot.
- if (S.PerformImplicitConversion(Init, DeclType, "initializing", DirectInit))
- return S.Diag(Init->getSourceRange().getBegin(),
- diag::err_typecheck_convert_incompatible)
- << DeclType << Init->getType() << "initializing"
- << Init->getSourceRange();
+ if (S.PerformImplicitConversion(Init, DeclType,
+ "initializing", DirectInit)) {
+ ImplicitConversionSequence ICS;
+ OverloadCandidateSet CandidateSet;
+ if (S.IsUserDefinedConversion(Init, DeclType, ICS.UserDefined,
+ CandidateSet,
+ true, false, false) != S.OR_Ambiguous)
+ return S.Diag(Init->getSourceRange().getBegin(),
+ diag::err_typecheck_convert_incompatible)
+ << DeclType << Init->getType() << "initializing"
+ << Init->getSourceRange();
+ S.Diag(Init->getSourceRange().getBegin(),
+ diag::err_typecheck_convert_ambiguous)
+ << DeclType << Init->getType() << Init->getSourceRange();
+ S.PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+ return true;
+ }
return false;
}
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=81898&r1=81897&r2=81898&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Sep 15 14:12:21 2009
@@ -417,7 +417,7 @@
IsUserDefinedConversion(From, ToType, ICS.UserDefined,
Conversions,
!SuppressUserConversions, AllowExplicit,
- ForceRValue)) {
+ ForceRValue) == OR_Success) {
ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
// C++ [over.ics.user]p4:
// A conversion of an expression of class type to the same class
@@ -1355,7 +1355,8 @@
///
/// \param ForceRValue true if the expression should be treated as an rvalue
/// for overload resolution.
-bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
+Sema::OverloadingResult Sema::IsUserDefinedConversion(
+ Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
OverloadCandidateSet& CandidateSet,
bool AllowConversionFunctions,
@@ -1458,7 +1459,7 @@
User.After.FromTypePtr
= ThisType->getAs<PointerType>()->getPointeeType().getAsOpaquePtr();
User.After.ToTypePtr = ToType.getAsOpaquePtr();
- return true;
+ return OR_Success;
} else if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(Best->Function)) {
// C++ [over.ics.user]p1:
@@ -1480,24 +1481,25 @@
// user-defined conversion sequence (see 13.3.3 and
// 13.3.3.1).
User.After = Best->FinalConversion;
- return true;
+ return OR_Success;
} else {
assert(false && "Not a constructor or conversion function?");
- return false;
+ return OR_No_Viable_Function;
}
case OR_No_Viable_Function:
+ return OR_No_Viable_Function;
case OR_Deleted:
// No conversion here! We're done.
- return false;
+ return OR_Deleted;
case OR_Ambiguous:
// FIXME: See C++ [over.best.ics]p10 for the handling of
// ambiguous conversion sequences.
- return false;
+ return OR_Ambiguous;
}
- return false;
+ return OR_No_Viable_Function;
}
/// CompareImplicitConversionSequences - Compare two implicit
@@ -2100,10 +2102,9 @@
return false;
OverloadCandidateSet CandidateSet;
- IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined,
+ if (IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined,
CandidateSet,
- true, true, false);
- if (CandidateSet.begin() == CandidateSet.end())
+ true, true, false) != OR_Ambiguous)
return Diag(From->getSourceRange().getBegin(),
diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
Modified: cfe/trunk/test/SemaCXX/deleted-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deleted-function.cpp?rev=81898&r1=81897&r2=81898&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/deleted-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/deleted-function.cpp Tue Sep 15 14:12:21 2009
@@ -18,7 +18,7 @@
struct WithDel {
WithDel() = delete; // expected-note {{candidate function has been explicitly deleted}}
void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
- operator int() = delete;
+ operator int() = delete;
void operator +(int) = delete;
int i = delete; // expected-error {{only functions can have deleted definitions}}
Modified: cfe/trunk/test/SemaCXX/direct-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/direct-initializer.cpp?rev=81898&r1=81897&r2=81898&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/direct-initializer.cpp (original)
+++ cfe/trunk/test/SemaCXX/direct-initializer.cpp Tue Sep 15 14:12:21 2009
@@ -34,3 +34,17 @@
Z z; // expected-error{{no matching constructor for initialization of 'z'}}
}
+
+struct Base {
+ operator int*() const; // expected-note {{candidate function}}
+};
+
+struct Derived : Base {
+ operator int*(); // expected-note {{candidate function}}
+};
+
+void foo(const Derived cd, Derived d) {
+ int *pi = cd;
+ int *ppi = d; // expected-error {{ambiguity in initializing value of type 'int *' with initializer of type 'struct Derived'}}
+
+}
More information about the cfe-commits
mailing list