From: Richard Smith Date: Wed, 23 Feb 2011 00:37:57 +0000 (+0000) Subject: Fix PR9276: We were missing the checks for auto deducing to different types in the... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=406c38e8c1f105acfd438f94dfbc17af817aa4a5;p=clang Fix PR9276: We were missing the checks for auto deducing to different types in the same declaration group in the template instantiation case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126279 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 2644b0f4c7..243ada2dde 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -864,6 +864,8 @@ public: 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); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 3c62c18558..c57efe32bc 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5055,6 +5055,19 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, 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 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, // 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(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 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, 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 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, } } - 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)); } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 944e6a13e1..04ec04110b 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1083,11 +1083,8 @@ public: 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. diff --git a/test/SemaCXX/dependent-auto.cpp b/test/SemaCXX/dependent-auto.cpp index 0ea59481d5..52b15eda73 100644 --- a/test/SemaCXX/dependent-auto.cpp +++ b/test/SemaCXX/dependent-auto.cpp @@ -32,3 +32,28 @@ bool h(T t) { } 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 + 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(); // expected-note {{here}} + f(); + } +} + +namespace NoRepeatedDiagnostic { + template + 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(); + template void f(); + template void f(); +}