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