[cfe-commits] r94303 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp test/SemaCXX/overload-call.cpp

John McCall rjmccall at apple.com
Sat Jan 23 00:10:49 PST 2010


Author: rjmccall
Date: Sat Jan 23 02:10:49 2010
New Revision: 94303

URL: http://llvm.org/viewvc/llvm-project?rev=94303&view=rev
Log:
Produce a special diagnostic when users call a function with an argument of
incomplete type (or a pointer/reference to such).

The causes of this problem are different enough to justify a different "design"
for the diagnostic.  Most notably, it doesn't give an operand index:
it's usually pretty obvious which operand is the problem, it adds a lot of
clutter to mention it, and the fix is usually in a different part of the file
anyway.

This is yet another diagnostic that should really have an analogue in the
non-overloaded case --- which should be much easier to write because of
the weaker space constraints.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/overload-call.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=94303&r1=94302&r2=94303&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Jan 23 02:10:49 2010
@@ -923,10 +923,24 @@
     "function (the implicit copy assignment operator)}0 not viable: requires"
     "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 "
     "provided">;
+
 def note_ovl_candidate_deleted : Note<
   "candidate %select{function|function|constructor|"
   "function |function |constructor |||}0%1 "
   "has been explicitly %select{made unavailable|deleted}2">;
+
+// Giving the index of the bad argument really clutters this message, and
+// it's relatively unimportant because 1) it's generally obvious which
+// argument(s) are of the given object type and 2) the fix is usually
+// to complete the type, which doesn't involve changes to the call line
+// anyway.  If people complain, we can change it.
+def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1 "
+    "not viable: cannot convert argument of incomplete type %2 to %3">;
 def note_ovl_candidate_bad_conv : Note<"candidate "
     "%select{function|function|constructor|"
     "function |function |constructor |"

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=94303&r1=94302&r2=94303&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jan 23 02:10:49 2010
@@ -4414,7 +4414,8 @@
   QualType FromTy = Conv.Bad.getFromType();
   QualType ToTy = Conv.Bad.getToType();
 
-  // Do some hand-waving analysis to see if the non-viability is due to a
+  // Do some hand-waving analysis to see if the non-viability is due
+  // to a qualifier mismatch.
   CanQualType CFromTy = S.Context.getCanonicalType(FromTy);
   CanQualType CToTy = S.Context.getCanonicalType(ToTy);
   if (CanQual<ReferenceType> RT = CToTy->getAs<ReferenceType>())
@@ -4464,6 +4465,20 @@
     return;
   }
 
+  // Diagnose references or pointers to incomplete types differently,
+  // since it's far from impossible that the incompleteness triggered
+  // the failure.
+  QualType TempFromTy = FromTy.getNonReferenceType();
+  if (const PointerType *PTy = TempFromTy->getAs<PointerType>())
+    TempFromTy = PTy->getPointeeType();
+  if (TempFromTy->isIncompleteType()) {
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
+      << (unsigned) FnKind << FnDesc
+      << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+      << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+    return;
+  }
+
   // TODO: specialize more based on the kind of mismatch
   S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
     << (unsigned) FnKind << FnDesc

Modified: cfe/trunk/test/SemaCXX/overload-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=94303&r1=94302&r2=94303&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/overload-call.cpp (original)
+++ cfe/trunk/test/SemaCXX/overload-call.cpp Sat Jan 23 02:10:49 2010
@@ -333,3 +333,17 @@
     inline bool operator!=(const qrgb666 &v) const { return !(*this == v); }
   };
 }
+
+// PR 6117
+namespace test3 {
+  struct Base {};
+  struct Incomplete;
+
+  void foo(Base *); // expected-note 2 {{cannot convert argument of incomplete type}}
+  void foo(Base &); // expected-note 2 {{cannot convert argument of incomplete type}}
+
+  void test(Incomplete *P) {
+    foo(P); // expected-error {{no matching function for call to 'foo'}}
+    foo(*P); // expected-error {{no matching function for call to 'foo'}}
+  }
+}





More information about the cfe-commits mailing list