[cfe-commits] r163845 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/attr-noreturn.cpp
Douglas Gregor
dgregor at apple.com
Thu Sep 13 14:56:43 PDT 2012
Author: dgregor
Date: Thu Sep 13 16:56:43 2012
New Revision: 163845
URL: http://llvm.org/viewvc/llvm-project?rev=163845&view=rev
Log:
When we substitute into the type of a function based on the
TypeSourceInfo, we may have lost some adjustments made to the type of
that function due to declaration merging. Adjust the resulting type
correspondingly. Fixes PR12948 / <rdar://problem/11552434>.
Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/attr-noreturn.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=163845&r1=163844&r2=163845&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Sep 13 16:56:43 2012
@@ -1008,6 +1008,21 @@
return Record;
}
+/// \brief Adjust the given function type for an instantiation of the
+/// given declaration, to cope with modifications to the function's type that
+/// aren't reflected in the type-source information.
+///
+/// \param D The declaration we're instantiating.
+/// \param TInfo The already-instantiated type.
+static QualType adjustFunctionTypeForInstantiation(ASTContext &Context,
+ FunctionDecl *D,
+ TypeSourceInfo *TInfo) {
+ const FunctionType *OrigFunc = D->getType()->castAs<FunctionType>();
+ const FunctionType *NewFunc = TInfo->getType()->castAs<FunctionType>();
+ return QualType(Context.adjustFunctionType(NewFunc, OrigFunc->getExtInfo()),
+ 0);
+}
+
/// Normal class members are of more specific types and therefore
/// don't make it here. This function serves two purposes:
/// 1) instantiating function templates
@@ -1048,7 +1063,7 @@
TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
if (!TInfo)
return 0;
- QualType T = TInfo->getType();
+ QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
if (QualifierLoc) {
@@ -1366,7 +1381,7 @@
TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
if (!TInfo)
return 0;
- QualType T = TInfo->getType();
+ QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
// \brief If the type of this function, after ignoring parentheses,
// is not *directly* a function type, then we're instantiating a function
Modified: cfe/trunk/test/SemaCXX/attr-noreturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-noreturn.cpp?rev=163845&r1=163844&r2=163845&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-noreturn.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-noreturn.cpp Thu Sep 13 16:56:43 2012
@@ -54,3 +54,29 @@
int xpto::blah() {
return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}
}
+
+// PR12948
+
+namespace PR12948 {
+ template<int>
+ void foo() __attribute__((__noreturn__));
+
+ template<int>
+ void foo() {
+ while (1) continue;
+ }
+
+ void bar() __attribute__((__noreturn__));
+
+ void bar() {
+ foo<0>();
+ }
+
+
+ void baz() __attribute__((__noreturn__));
+ typedef void voidfn();
+ voidfn baz;
+
+ template<typename> void wibble() __attribute__((__noreturn__));
+ template<typename> voidfn wibble;
+}
More information about the cfe-commits
mailing list