r180808 - When deducing an 'auto' type, don't modify the type-as-written.

Richard Smith richard-llvm at metafoo.co.uk
Tue Apr 30 14:23:01 PDT 2013


Author: rsmith
Date: Tue Apr 30 16:23:01 2013
New Revision: 180808

URL: http://llvm.org/viewvc/llvm-project?rev=180808&view=rev
Log:
When deducing an 'auto' type, don't modify the type-as-written.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=180808&r1=180807&r2=180808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Apr 30 16:23:01 2013
@@ -5643,7 +5643,7 @@ public:
   };
 
   DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
-                                  TypeSourceInfo *&Result);
+                                  QualType &Result);
   QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
   void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
 

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=180808&r1=180807&r2=180808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Apr 30 16:23:01 2013
@@ -7334,17 +7334,16 @@ void Sema::AddInitializerToDecl(Decl *Re
       Init = Result.take();
       DefaultedToAuto = true;
     }
-    
-    TypeSourceInfo *DeducedType = 0;
+
+    QualType DeducedType;
     if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) ==
             DAR_Failed)
       DiagnoseAutoDeductionFailure(VDecl, DeduceInit);
-    if (!DeducedType) {
+    if (DeducedType.isNull()) {
       RealDecl->setInvalidDecl();
       return;
     }
-    VDecl->setTypeSourceInfo(DeducedType);
-    VDecl->setType(DeducedType->getType());
+    VDecl->setType(DeducedType);
     assert(VDecl->isLinkageValid());
 
     // In ARC, infer lifetime.
@@ -7356,8 +7355,9 @@ void Sema::AddInitializerToDecl(Decl *Re
     // We only want to warn outside of template instantiations, though:
     // inside a template, the 'id' could have come from a parameter.
     if (ActiveTemplateInstantiations.empty() && !DefaultedToAuto &&
-        DeducedType->getType()->isObjCIdType()) {
-      SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc();
+        DeducedType->isObjCIdType()) {
+      SourceLocation Loc =
+          VDecl->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
       Diag(Loc, diag::warn_auto_var_is_id)
         << VDecl->getDeclName() << DeduceInit->getSourceRange();
     }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=180808&r1=180807&r2=180808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Apr 30 16:23:01 2013
@@ -1133,16 +1133,14 @@ Sema::BuildCXXNew(SourceRange Range, boo
                        << AllocType << TypeRange);
     }
     Expr *Deduce = Inits[0];
-    TypeSourceInfo *DeducedType = 0;
+    QualType DeducedType;
     if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
                        << AllocType << Deduce->getType()
                        << TypeRange << Deduce->getSourceRange());
-    if (!DeducedType)
+    if (DeducedType.isNull())
       return ExprError();
-
-    AllocTypeInfo = DeducedType;
-    AllocType = AllocTypeInfo->getType();
+    AllocType = DeducedType;
   }
 
   // Per C++0x [expr.new]p5, the type being constructed may be a

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=180808&r1=180807&r2=180808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue Apr 30 16:23:01 2013
@@ -1590,25 +1590,22 @@ Sema::ActOnObjCForCollectionStmt(SourceL
 
       // If the type contained 'auto', deduce the 'auto' to 'id'.
       if (FirstType->getContainedAutoType()) {
-        TypeSourceInfo *DeducedType = 0;
         OpaqueValueExpr OpaqueId(D->getLocation(), Context.getObjCIdType(),
                                  VK_RValue);
         Expr *DeducedInit = &OpaqueId;
-        if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, DeducedType)
-              == DAR_Failed) {
+        if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, FirstType) ==
+                DAR_Failed)
           DiagnoseAutoDeductionFailure(D, DeducedInit);
-        }
-        if (!DeducedType) {
+        if (FirstType.isNull()) {
           D->setInvalidDecl();
           return StmtError();
         }
 
-        D->setTypeSourceInfo(DeducedType);
-        D->setType(DeducedType->getType());
-        FirstType = DeducedType->getType();
+        D->setType(FirstType);
 
         if (ActiveTemplateInstantiations.empty()) {
-          SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc();
+          SourceLocation Loc =
+              D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
           Diag(Loc, diag::warn_auto_var_is_id)
             << D->getDeclName();
         }
@@ -1645,20 +1642,19 @@ Sema::ActOnObjCForCollectionStmt(SourceL
 /// Finish building a variable declaration for a for-range statement.
 /// \return true if an error occurs.
 static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
-                                  SourceLocation Loc, int diag) {
+                                  SourceLocation Loc, int DiagID) {
   // Deduce the type for the iterator variable now rather than leaving it to
   // AddInitializerToDecl, so we can produce a more suitable diagnostic.
-  TypeSourceInfo *InitTSI = 0;
+  QualType InitType;
   if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) ||
-      SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTSI) ==
+      SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitType) ==
           Sema::DAR_Failed)
-    SemaRef.Diag(Loc, diag) << Init->getType();
-  if (!InitTSI) {
+    SemaRef.Diag(Loc, DiagID) << Init->getType();
+  if (InitType.isNull()) {
     Decl->setInvalidDecl();
     return true;
   }
-  Decl->setTypeSourceInfo(InitTSI);
-  Decl->setType(InitTSI->getType());
+  Decl->setType(InitType);
 
   // In ARC, infer lifetime.
   // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=180808&r1=180807&r2=180808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Apr 30 16:23:01 2013
@@ -3600,32 +3600,32 @@ namespace {
       // Lambdas never need to be transformed.
       return E;
     }
+
+    QualType Apply(TypeSourceInfo *TSI) {
+      if (TypeSourceInfo *Result = TransformType(TSI))
+        return Result->getType();
+      return QualType();
+    }
   };
 }
 
-/// \brief Deduce the type for an auto type-specifier (C++0x [dcl.spec.auto]p6)
+/// \brief Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
 ///
 /// \param Type the type pattern using the auto type-specifier.
-///
 /// \param Init the initializer for the variable whose type is to be deduced.
-///
 /// \param Result if type deduction was successful, this will be set to the
-/// deduced type. This may still contain undeduced autos if the type is
-/// dependent. This will be set to null if deduction succeeded, but auto
-/// substitution failed; the appropriate diagnostic will already have been
-/// produced in that case.
+///        deduced type.
 Sema::DeduceAutoResult
-Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
-                     TypeSourceInfo *&Result) {
+Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result) {
   if (Init->getType()->isNonOverloadPlaceholderType()) {
-    ExprResult result = CheckPlaceholderExpr(Init);
-    if (result.isInvalid()) return DAR_FailedAlreadyDiagnosed;
-    Init = result.take();
+    ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
+    if (NonPlaceholder.isInvalid())
+      return DAR_FailedAlreadyDiagnosed;
+    Init = NonPlaceholder.take();
   }
 
   if (Init->isTypeDependent() || Type->getType()->isDependentType()) {
-    Result =
-        SubstituteAutoTransform(*this, Context.DependentTy).TransformType(Type);
+    Result = SubstituteAutoTransform(*this, Context.DependentTy).Apply(Type);
     return DAR_Succeeded;
   }
 
@@ -3642,7 +3642,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Typ
       QualType Deduced = BuildDecltypeType(Init, Init->getLocStart());
       // FIXME: Support a non-canonical deduced type for 'auto'.
       Deduced = Context.getCanonicalType(Deduced);
-      Result = SubstituteAutoTransform(*this, Deduced).TransformType(Type);
+      Result = SubstituteAutoTransform(*this, Deduced).Apply(Type);
       return DAR_Succeeded;
     }
   }
@@ -3660,10 +3660,9 @@ Sema::DeduceAutoType(TypeSourceInfo *Typ
   FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr,
                                                    Loc);
 
-  TypeSourceInfo *FuncParamInfo =
-    SubstituteAutoTransform(*this, TemplArg).TransformType(Type);
-  assert(FuncParamInfo && "substituting template parameter for 'auto' failed");
-  QualType FuncParam = FuncParamInfo->getType();
+  QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type);
+  assert(!FuncParam.isNull() &&
+         "substituting template parameter for 'auto' failed");
 
   // Deduce type of TemplParam in Func(Init)
   SmallVector<DeducedTemplateArgument, 1> Deduced;
@@ -3704,15 +3703,15 @@ Sema::DeduceAutoType(TypeSourceInfo *Typ
       return DAR_FailedAlreadyDiagnosed;
   }
 
-  Result = SubstituteAutoTransform(*this, DeducedType).TransformType(Type);
+  Result = SubstituteAutoTransform(*this, DeducedType).Apply(Type);
 
   // Check that the deduced argument type is compatible with the original
   // argument type per C++ [temp.deduct.call]p4.
-  if (!InitList && Result &&
-      CheckOriginalCallArgDeduction(*this, 
+  if (!InitList && !Result.isNull() &&
+      CheckOriginalCallArgDeduction(*this,
                                     Sema::OriginalCallArg(FuncParam,0,InitType),
-                                    Result->getType())) {
-    Result = 0;
+                                    Result)) {
+    Result = QualType();
     return DAR_Failed;
   }
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=180808&r1=180807&r2=180808&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Tue Apr 30 16:23:01 2013
@@ -3416,10 +3416,12 @@ TEST(TypeMatching, MatchesAutoTypes) {
   EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
                       autoType()));
 
-  EXPECT_TRUE(matches("auto a = 1;",
-                      autoType(hasDeducedType(isInteger()))));
-  EXPECT_TRUE(notMatches("auto b = 2.0;",
-                         autoType(hasDeducedType(isInteger()))));
+  // FIXME: Matching against the type-as-written can't work here, because the
+  //        type as written was not deduced.
+  //EXPECT_TRUE(matches("auto a = 1;",
+  //                    autoType(hasDeducedType(isInteger()))));
+  //EXPECT_TRUE(notMatches("auto b = 2.0;",
+  //                       autoType(hasDeducedType(isInteger()))));
 }
 
 TEST(TypeMatching, MatchesFunctionTypes) {





More information about the cfe-commits mailing list