summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2010-02-24 02:27:18 +0000
committerCharles Davis <cdavis@mines.edu>2010-02-24 02:27:18 +0000
commit29967969722ee3d425a5f5456d02cf98d03971a2 (patch)
treeeb61c1850b9690815e21f186c82d71a2110c449f
parenta396e617b54e0ba138fa5db30d0893ecb7db3c32 (diff)
downloadbcm5719-llvm-29967969722ee3d425a5f5456d02cf98d03971a2.tar.gz
bcm5719-llvm-29967969722ee3d425a5f5456d02cf98d03971a2.zip
When we encounter a function-specific attribute in a declaration specifier,
apply it only to the function itself, and never to the return type. Fixes part of PR6408. llvm-svn: 97015
-rw-r--r--clang/lib/Sema/SemaType.cpp14
-rw-r--r--clang/test/Sema/callingconv.c4
2 files changed, 13 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f5e6bef7198..2fb5c84ac90 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -72,6 +72,7 @@ typedef std::pair<const AttributeList*,QualType> DelayedAttribute;
typedef llvm::SmallVectorImpl<DelayedAttribute> DelayedAttributeSet;
static void ProcessTypeAttributeList(Sema &S, QualType &Type,
+ bool IsDeclSpec,
const AttributeList *Attrs,
DelayedAttributeSet &DelayedFnAttrs);
static bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr);
@@ -385,7 +386,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
// See if there are any attributes on the declspec that apply to the type (as
// opposed to the decl).
if (const AttributeList *AL = DS.getAttributes())
- ProcessTypeAttributeList(TheSema, Result, AL, Delayed);
+ ProcessTypeAttributeList(TheSema, Result, true, AL, Delayed);
// Apply const/volatile/restrict qualifiers to T.
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
@@ -1297,7 +1298,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// See if there are any attributes on this declarator chunk.
if (const AttributeList *AL = DeclType.getAttrs())
- ProcessTypeAttributeList(*this, T, AL, FnAttrsFromPreviousChunk);
+ ProcessTypeAttributeList(*this, T, false, AL, FnAttrsFromPreviousChunk);
}
if (getLangOptions().CPlusPlus && T->isFunctionType()) {
@@ -1337,7 +1338,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// block-literal expressions, which are parsed wierdly.
if (D.getContext() != Declarator::BlockLiteralContext)
if (const AttributeList *Attrs = D.getAttributes())
- ProcessTypeAttributeList(*this, T, Attrs, FnAttrsFromPreviousChunk);
+ ProcessTypeAttributeList(*this, T, false, Attrs,
+ FnAttrsFromPreviousChunk);
DiagnoseDelayedFnAttrs(*this, FnAttrsFromPreviousChunk);
@@ -1834,7 +1836,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S
}
void ProcessTypeAttributeList(Sema &S, QualType &Result,
- const AttributeList *AL,
+ bool IsDeclSpec, const AttributeList *AL,
DelayedAttributeSet &FnAttrs) {
// Scan through and apply attributes to this type where it makes sense. Some
// attributes (such as __address_space__, __vector_size__, etc) apply to the
@@ -1860,7 +1862,9 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result,
case AttributeList::AT_cdecl:
case AttributeList::AT_fastcall:
case AttributeList::AT_stdcall:
- if (ProcessFnAttr(S, Result, *AL))
+ // Don't process these on the DeclSpec.
+ if (IsDeclSpec ||
+ ProcessFnAttr(S, Result, *AL))
FnAttrs.push_back(DelayedAttribute(AL, Result));
break;
}
diff --git a/clang/test/Sema/callingconv.c b/clang/test/Sema/callingconv.c
index 424db751b64..92a20572a2c 100644
--- a/clang/test/Sema/callingconv.c
+++ b/clang/test/Sema/callingconv.c
@@ -40,3 +40,7 @@ Handler H = foo;
void ctest3();
void __attribute__((cdecl)) ctest3() {}
+// PR6408
+typedef __attribute__((stdcall)) void (*PROC)();
+PROC __attribute__((cdecl)) ctest4(const char *x) {}
+
OpenPOWER on IntegriCloud