[cfe-commits] r126279 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/TreeTransform.h test/SemaCXX/dependent-auto.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Feb 22 16:37:57 PST 2011


Author: rsmith
Date: Tue Feb 22 18:37:57 2011
New Revision: 126279

URL: http://llvm.org/viewvc/llvm-project?rev=126279&view=rev
Log:
Fix PR9276: We were missing the checks for auto deducing to different types in the same declaration group in the template instantiation case.


Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaCXX/dependent-auto.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=126279&r1=126278&r2=126279&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Feb 22 18:37:57 2011
@@ -864,6 +864,8 @@
   DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                          Decl **Group,
                                          unsigned NumDecls);
+  DeclGroupPtrTy BuildDeclaratorGroup(Decl **Group, unsigned NumDecls,
+                                      bool TypeMayContainAuto = true);
   void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
                                        SourceLocation LocAfterDecls);
   Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=126279&r1=126278&r2=126279&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Feb 22 18:37:57 2011
@@ -5055,6 +5055,19 @@
   if (DS.isTypeSpecOwned())
     Decls.push_back(DS.getRepAsDecl());
 
+  for (unsigned i = 0; i != NumDecls; ++i)
+    if (Decl *D = Group[i])
+      Decls.push_back(D);
+
+  return BuildDeclaratorGroup(Decls.data(), Decls.size(), 
+                              DS.getTypeSpecType() == DeclSpec::TST_auto);
+}
+
+/// BuildDeclaratorGroup - convert a list of declarations into a declaration
+/// group, performing any necessary semantic checking.
+Sema::DeclGroupPtrTy
+Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls,
+                           bool TypeMayContainAuto) {
   // C++0x [dcl.spec.auto]p7:
   //   If the type deduced for the template parameter U is not the same in each
   //   deduction, the program is ill-formed.
@@ -5062,14 +5075,16 @@
   // between the deduced type U and the deduced type which 'auto' stands for.
   //   auto a = 0, b = { 1, 2, 3 };
   // is legal because the deduced type U is 'int' in both cases.
-  bool TypeContainsAuto = DS.getTypeSpecType() == DeclSpec::TST_auto;
-  if (TypeContainsAuto && NumDecls > 1) {
+  if (TypeMayContainAuto && NumDecls > 1) {
     QualType Deduced;
     CanQualType DeducedCanon;
     VarDecl *DeducedDecl = 0;
     for (unsigned i = 0; i != NumDecls; ++i) {
       if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) {
         AutoType *AT = D->getType()->getContainedAutoType();
+        // Don't reissue diagnostics when instantiating a template.
+        if (AT && D->isInvalidDecl())
+          break;
         if (AT && AT->isDeduced()) {
           QualType U = AT->getDeducedType();
           CanQualType UCanon = Context.getCanonicalType(U);
@@ -5078,11 +5093,13 @@
             DeducedCanon = UCanon;
             DeducedDecl = D;
           } else if (DeducedCanon != UCanon) {
-            Diag(DS.getTypeSpecTypeLoc(), diag::err_auto_different_deductions)
+            Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
+                 diag::err_auto_different_deductions)
               << Deduced << DeducedDecl->getDeclName()
               << U << D->getDeclName()
               << DeducedDecl->getInit()->getSourceRange()
               << D->getInit()->getSourceRange();
+            D->setInvalidDecl();
             break;
           }
         }
@@ -5090,12 +5107,7 @@
     }
   }
 
-  for (unsigned i = 0; i != NumDecls; ++i)
-    if (Decl *D = Group[i])
-      Decls.push_back(D);
-
-  return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
-                                                   Decls.data(), Decls.size()));
+  return DeclGroupPtrTy::make(DeclGroupRef::Create(Context, Group, NumDecls));
 }
 
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=126279&r1=126278&r2=126279&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Feb 22 18:37:57 2011
@@ -1083,11 +1083,8 @@
   StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc) {
-    return getSema().Owned(
-             new (getSema().Context) DeclStmt(
-                                        DeclGroupRef::Create(getSema().Context,
-                                                             Decls, NumDecls),
-                                              StartLoc, EndLoc));
+    Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls, NumDecls);
+    return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
   }
 
   /// \brief Build a new inline asm statement.

Modified: cfe/trunk/test/SemaCXX/dependent-auto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dependent-auto.cpp?rev=126279&r1=126278&r2=126279&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dependent-auto.cpp (original)
+++ cfe/trunk/test/SemaCXX/dependent-auto.cpp Tue Feb 22 18:37:57 2011
@@ -32,3 +32,28 @@
 }
 
 bool b = h('x'); // expected-note {{here}}
+
+// PR 9276 - Make sure we check auto types deduce the same
+// in the case of a dependent initializer
+namespace PR9276 {
+  template<typename T>
+  void f() {
+    auto i = T(), j = 0; // expected-error {{deduced as 'long' in declaration of 'i' and deduced as 'int' in declaration of 'j'}}
+  }
+
+  void g() {
+    f<long>(); // expected-note {{here}}
+    f<int>();
+  }
+}
+
+namespace NoRepeatedDiagnostic {
+  template<typename T>
+  void f() {
+    auto a = 0, b = 0.0, c = T(); // expected-error {{deduced as 'int' in declaration of 'a' and deduced as 'double' in declaration of 'b'}}
+  }
+  // We've already diagnosed an issue. No extra diagnostics is needed for these.
+  template void f<int>();
+  template void f<double>();
+  template void f<char>();
+}





More information about the cfe-commits mailing list