From 3f224b2efde9b02dcc78c5c85667a62dcd1f5ab3 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Tue, 20 Sep 2011 04:55:26 +0000 Subject: [PATCH] Fix a pretty nasty bug in noreturn destructors that cascaded into lots of false positive warnings that depend on noreturn destructors pruning the CFGs, but only in C++0x mode! This was really surprising as the debugger quickly reveals that the attributes are parsed correctly (and using the same code) in both modes. The warning fires in the same way in both modes. But between parsing and building the destructor declaration with the noreturn attribute and the warning, it magically disappears. The key? The 'noexcept' appears! When we were rebuilding the destructor type with the computed implicit noexcept we completely dropped the old type on the floor. This almost makes sense (as the arguments and return type to a destructor aren't exactly unpredictable), but lost any function type attributes as well. The fix is simple, we build the new type off of the old one rather than starting fresh. Testing this is a bit awkward. I've done it by running the noreturn-sensitive tests in both modes, which previous failed and now passes, but if anyone has ideas about how to more specifically and thoroughly test that the extended info on a destructor is preserved when adding noexcept, I'm all ears. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140138 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 6 ++++-- test/SemaCXX/return-noreturn.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 37a4026b58..67b1274c2c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6964,8 +6964,10 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl, ImplicitExceptionSpecification exceptSpec = ComputeDefaultedDtorExceptionSpec(classDecl); - // Replace the destructor's type. - FunctionProtoType::ExtProtoInfo epi; + // Replace the destructor's type, building off the existing one. Fortunately, + // the only thing of interest in the destructor type is its extended info. + // The return and arguments are fixed. + FunctionProtoType::ExtProtoInfo epi = dtorType->getExtProtoInfo(); epi.ExceptionSpecType = exceptSpec.getExceptionSpecType(); epi.NumExceptions = exceptSpec.size(); epi.Exceptions = exceptSpec.data(); diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp index 2109efc19e..1fcccd4945 100644 --- a/test/SemaCXX/return-noreturn.cpp +++ b/test/SemaCXX/return-noreturn.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code +// RUN: %clang_cc1 %s -fsyntax-only -std=c++0x -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code // A destructor may be marked noreturn and should still influence the CFG. void pr6884_abort() __attribute__((noreturn)); -- 2.40.0