]> granicus.if.org Git - clang/commitdiff
Continue to instantiate sub-statements in a CompoundStmt as long as
authorJohn McCall <rjmccall@apple.com>
Fri, 27 Aug 2010 19:56:05 +0000 (19:56 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 27 Aug 2010 19:56:05 +0000 (19:56 +0000)
we don't see a DeclStmt (failure to instantiate which generally causes
panic).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112282 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/TreeTransform.h
test/SemaCXX/member-pointer.cpp
test/SemaTemplate/instantiate-clang.cpp
test/SemaTemplate/instantiate-expr-3.cpp
test/SemaTemplate/instantiate-expr-4.cpp
test/SemaTemplate/instantiate-function-1.cpp

index a796f2eaff94ed89f5ab1698d7c4f539f817eeee..dbc02d8727207823013af573cfdd1f06f42f3e35 100644 (file)
@@ -3440,18 +3440,30 @@ template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
                                               bool IsStmtExpr) {
+  bool SubStmtInvalid = false;
   bool SubStmtChanged = false;
   ASTOwningVector<Stmt*> Statements(getSema());
   for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
        B != BEnd; ++B) {
     StmtResult Result = getDerived().TransformStmt(*B);
-    if (Result.isInvalid())
-      return StmtError();
+    if (Result.isInvalid()) {
+      // Immediately fail if this was a DeclStmt, since it's very
+      // likely that this will cause problems for future statements.
+      if (isa<DeclStmt>(*B))
+        return StmtError();
+
+      // Otherwise, just keep processing substatements and fail later.
+      SubStmtInvalid = true;
+      continue;
+    }
 
     SubStmtChanged = SubStmtChanged || Result.get() != *B;
     Statements.push_back(Result.takeAs<Stmt>());
   }
 
+  if (SubStmtInvalid)
+    return StmtError();
+
   if (!getDerived().AlwaysRebuild() &&
       !SubStmtChanged)
     return SemaRef.Owned(S->Retain());
index 83823f69c6373be2878fe0c6e2aa1054dd511a4b..795c0b95efd6d9714f3a39b2d3537f49134e1e46 100644 (file)
@@ -179,13 +179,11 @@ namespace rdar8358512 {
   // We can't call this with an overload set because we're not allowed
   // to look into overload sets unless the parameter has some kind of
   // function type.
-  template <class F> void bind(F f); // expected-note 6 {{candidate template ignored}}
+  template <class F> void bind(F f); // expected-note 12 {{candidate template ignored}}
   template <class F, class T> void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}}
   template <class F> void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}}
 
   struct A {
-    void member();
-
     void nonstat();
     void nonstat(int);
 
@@ -234,4 +232,41 @@ namespace rdar8358512 {
       }
     };
   };
+
+  template <class T> class B {
+    void nonstat();
+    void nonstat(int);
+
+    void mixed();
+    static void mixed(int);
+
+    static void stat();
+    static void stat(int);
+
+    // None of these can be diagnosed yet, because the arguments are
+    // still dependent.
+    void test0a() {
+      bind(&nonstat);
+      bind(&B::nonstat);
+
+      bind(&mixed);
+      bind(&B::mixed);
+
+      bind(&stat);
+      bind(&B::stat);
+    }
+
+    void test0b() {
+      bind(&nonstat); // expected-error {{no matching function for call}}
+      bind(&B::nonstat); // expected-error {{no matching function for call}}
+
+      bind(&mixed); // expected-error {{no matching function for call}}
+      bind(&B::mixed); // expected-error {{no matching function for call}}
+
+      bind(&stat); // expected-error {{no matching function for call}}
+      bind(&B::stat); // expected-error {{no matching function for call}}
+    }
+  };
+
+  template void B<int>::test0b(); // expected-note {{in instantiation}}
 }
index cef2b7090bf2e6d59b311196592a44442ec28e1b..34d68c4e59fd5bcfa1cd39a57d5da478bb3027ba 100644 (file)
@@ -24,7 +24,7 @@ template<typename T, typename U, int N, int M>
 struct ShuffleVector0 {
   void f(T t, U u, double2 a, double2 b) {
     (void)__builtin_shufflevector(t, u, N, M); // expected-error{{index}}
-    (void)__builtin_shufflevector(a, b, N, M);
+    (void)__builtin_shufflevector(a, b, N, M); // expected-error{{index}}
     (void)__builtin_shufflevector(a, b, 2, 1);
   }
 };
index d506b19a7a9721d42a3b7c548261f9c1cb19336f..ca88b00300dcfa7de409a6543a96b72b5819ebd9 100644 (file)
@@ -63,7 +63,11 @@ template struct Conditional0<int, int, int>;
 template<typename T>
 struct StatementExpr0 {
   void f(T t) {
-    (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{contextually convertible}}
+    (void)({
+        if (t) // expected-error{{contextually convertible}}
+          t = t + 17;
+        t + 12; // expected-error{{invalid operands}}
+      });
   }
 };
 
@@ -106,8 +110,8 @@ struct VaArg1 {
     VaList va;
     __builtin_va_start(va, n); // expected-error{{int}}
     for (int i = 0; i != n; ++i)
-      (void)__builtin_va_arg(va, ArgType);
-    __builtin_va_end(va);
+      (void)__builtin_va_arg(va, ArgType); // expected-error{{int}}
+    __builtin_va_end(va); // expected-error{{int}}
   }
 };
 
index 8cd7342e98ebc6e9b46eeef05e1a2dd7239e39bd..adae1da26aaf5b35a144c794ac14bb5bd0fe3b43 100644 (file)
@@ -115,7 +115,7 @@ template<typename T>
 struct Delete0 {
   void f(T t) {
     delete t; // expected-error{{cannot delete}}
-    ::delete [] t;
+    ::delete [] t; // expected-error{{cannot delete}}
   }
 };
 
index a293e9a788decad494dd5972f449e1b0985cb79d..651c02c6cdcf57c7c359d38a1dcd9ac6d3934b56 100644 (file)
@@ -72,7 +72,7 @@ template<typename T, typename U, typename V> struct X6 {
     if (T x = t) {
       t = x;
     }
-    return v;
+    return v; // expected-error{{cannot initialize return object of type}}
   }
 };
 
@@ -178,10 +178,10 @@ template<typename T> struct IndirectGoto0 {
 
   prior:
     T prior_label;
-    prior_label = &&prior;
+    prior_label = &&prior; // expected-error{{assigning to 'int'}}
 
     T later_label;
-    later_label = &&later;
+    later_label = &&later; // expected-error{{assigning to 'int'}}
 
   later:
     (void)(1+1);