[patch] Don't assert when calling a pure method with exception spec of a template class

Nico Weber thakis at chromium.org
Tue Aug 26 14:18:56 PDT 2014


Ok, how does this look?

On Thu, Aug 21, 2014 at 1:28 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

> I'm a bit uncomfortable about duplicating a fragment of
> MarkFunctionReferenced here. Various other parts of MarkFunctionReferenced
> logically belong here too, but the problematic cases can't happen only
> because virtual functions can't be constexpr, nor can they have deduced
> return types.
>
> I wonder whether we should instead be passing the OdrUse flag into
> MarkFunctionReferenced and having it skip the things that don't happen for
> a reference that's not an odr-use.
>
>
> On Wed, Aug 20, 2014 at 8:08 PM, Nico Weber <thakis at chromium.org> wrote:
>
>> Ping :-)
>>
>>
>> On Sat, Aug 16, 2014 at 10:24 PM, Nico Weber <thakis at chromium.org> wrote:
>>
>>> Hi,
>>>
>>> clang  currently asserts on the following program when building with
>>> -std=c++11 (PR19190):
>>>
>>>   template <class T> struct DWFIterator { virtual T &get() throw(int) =
>>> 0; };
>>>   void foo(DWFIterator<int> *foo) { foo->get(); }
>>>
>>> This is because in C++11, instantiation of exception specs is deferred.
>>> This usually happens in MarkFunctionReferenced(), but that's never called
>>> for pure functions. So the exception spec stays unresolved, and codegen
>>> then complains about that. (See the bug for details.)
>>>
>>> The attached patch lets Sema::MarkAnyDeclReferenced()
>>> call ResolveExceptionSpec() for non-OdrUse functions. This fixes the assert
>>> and passes all tests, but I'm not sure if it's the best place to do this –
>>> hence, pre-commit review, please :-)
>>>
>>> Nico
>>>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140826/b6d1e573/attachment.html>
-------------- next part --------------
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 216461)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -3291,7 +3291,8 @@
   // 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);
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 216461)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -11398,7 +11398,8 @@
 
 /// \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 @@
   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,15 +12626,15 @@
 /// normal expression which refers to a variable.
 void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {
   if (OdrUse) {
-    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (auto *VD = dyn_cast<VarDecl>(D)) {
       MarkVariableReferenced(Loc, VD);
       return;
     }
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      MarkFunctionReferenced(Loc, FD);
-      return;
-    }
   }
+  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+    MarkFunctionReferenced(Loc, FD, OdrUse);
+    return;
+  }
   D->setReferenced();
 }
 
Index: test/CodeGenCXX/cxx11-exception-spec.cpp
===================================================================
--- test/CodeGenCXX/cxx11-exception-spec.cpp	(revision 216461)
+++ test/CodeGenCXX/cxx11-exception-spec.cpp	(working copy)
@@ -122,3 +122,8 @@
 
 // CHECK: attributes [[NONE]] = { {{.*}} }
 // CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+
+namespace PR19190 {
+template <class T> struct DWFIterator { virtual void get() throw(int) = 0; };
+void foo(DWFIterator<int> *foo) { foo->get(); }
+}


More information about the cfe-commits mailing list