]> granicus.if.org Git - clang/commitdiff
[Sema] Handle leading and trailing __ for GNU attributes
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 25 Aug 2015 16:44:38 +0000 (16:44 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 25 Aug 2015 16:44:38 +0000 (16:44 +0000)
GNU attributes can have a leading and trailing __ appended/prepended to
the attribute name.  While the parser and AttributeList::getKind did the
right thing, AttributeList::getAttributeSpellingListIndex did not.

This fixes PR24565.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245953 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/AttributeList.cpp
test/SemaCXX/attr-print.cpp

index 1ea40606f44b063b44c0ee76ffac925c5b0de13c..3c61c95ad8ec37e440340425adc3373929bf6eab 100644 (file)
@@ -109,6 +109,19 @@ void AttributePool::takePool(AttributeList *pool) {
 
 #include "clang/Sema/AttrParsedAttrKinds.inc"
 
+static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
+                                   AttributeList::Syntax SyntaxUsed) {
+  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
+  // for GNU attributes.
+  bool IsGNU = SyntaxUsed == AttributeList::AS_GNU ||
+               (SyntaxUsed == AttributeList::AS_CXX11 && ScopeName == "gnu");
+  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
+      AttrName.endswith("__"))
+    AttrName = AttrName.slice(2, AttrName.size() - 2);
+
+  return AttrName;
+}
+
 AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
                                            const IdentifierInfo *ScopeName,
                                            Syntax SyntaxUsed) {
@@ -118,13 +131,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
   if (ScopeName)
     FullName += ScopeName->getName();
 
-  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
-  // for GNU attributes.
-  bool IsGNU = SyntaxUsed == AS_GNU || (SyntaxUsed == AS_CXX11 &&
-                                        FullName == "gnu");
-  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
-      AttrName.endswith("__"))
-    AttrName = AttrName.slice(2, AttrName.size() - 2);
+  AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
 
   // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
   // unscoped.
@@ -138,8 +145,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
 unsigned AttributeList::getAttributeSpellingListIndex() const {
   // Both variables will be used in tablegen generated
   // attribute spell list index matching code.
-  StringRef Name = AttrName->getName();
   StringRef Scope = ScopeName ? ScopeName->getName() : "";
+  StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
+                                     (AttributeList::Syntax)SyntaxUsed);
 
 #include "clang/Sema/AttrSpellingListIndex.inc"
 
index 337a6fb69ba3c3c8d98c30c87f0bd991910f83ef..f40d803e94cbe6b50cfe587cc26a350df23a822d 100644 (file)
@@ -26,6 +26,9 @@ int small __attribute__((mode(byte)));
 // CHECK: int v __attribute__((visibility("hidden")));
 int v __attribute__((visibility("hidden")));
 
+// CHECK: char *PR24565() __attribute__((malloc))
+char *PR24565() __attribute__((__malloc__));
+
 // CHECK: class __attribute__((consumable("unknown"))) AttrTester1
 class __attribute__((consumable(unknown))) AttrTester1 {
   // CHECK: void callableWhen() __attribute__((callable_when("unconsumed", "consumed")));