From: Nico Weber Date: Wed, 27 Aug 2014 17:04:39 +0000 (+0000) Subject: Call ResolveExceptionSpec for non-OdrUsed functions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45440021a557a8171e95e2586ceb18ac84c32e3d;p=clang Call ResolveExceptionSpec for non-OdrUsed functions. In C++11, instantiation of exception specs is deferred. The instantiation is done in MarkFunctionReferenced(), which wasn't called for non-OdrUsed functions, which then caused an assert in codegen. Fixes PR19190, see the bug for details. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216562 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 7652d0afc5..856fa6cd9c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3293,7 +3293,8 @@ public: // needs to be delayed for some constant variables when we build one of the // named expressions. void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse); - void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func); + void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, + bool OdrUse = true); void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); void MarkDeclRefReferenced(DeclRefExpr *E); void MarkMemberReferenced(MemberExpr *E); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5bb042ce3d..6a530c71ec 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -11398,7 +11398,8 @@ static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) { /// \brief Mark a function referenced, and check whether it is odr-used /// (C++ [basic.def.odr]p2, C99 6.9p3) -void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { +void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, + bool OdrUse) { assert(Func && "No function?"); Func->setReferenced(); @@ -11497,6 +11498,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) ResolveExceptionSpec(Loc, FPT); + if (!OdrUse) return; + // Implicit instantiation of function templates and member functions of // class templates. if (Func->isImplicitlyInstantiable()) { @@ -12623,14 +12626,14 @@ void Sema::MarkMemberReferenced(MemberExpr *E) { /// normal expression which refers to a variable. void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) { if (OdrUse) { - if (VarDecl *VD = dyn_cast(D)) { + if (auto *VD = dyn_cast(D)) { MarkVariableReferenced(Loc, VD); return; } - if (FunctionDecl *FD = dyn_cast(D)) { - MarkFunctionReferenced(Loc, FD); - return; - } + } + if (auto *FD = dyn_cast(D)) { + MarkFunctionReferenced(Loc, FD, OdrUse); + return; } D->setReferenced(); } diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp index 3b1516b925..75f939f93f 100644 --- a/test/CodeGenCXX/cxx11-exception-spec.cpp +++ b/test/CodeGenCXX/cxx11-exception-spec.cpp @@ -122,3 +122,8 @@ void j() { // CHECK: attributes [[NONE]] = { {{.*}} } // CHECK: attributes [[NUW]] = { nounwind{{.*}} } + +namespace PR19190 { +template struct DWFIterator { virtual void get() throw(int) = 0; }; +void foo(DWFIterator *foo) { foo->get(); } +}