r225813 - When attribute 'optnone' appears on the same declaration with a

Paul Robinson paul_robinson at playstation.sony.com
Tue Jan 13 10:34:57 PST 2015


Author: probinson
Date: Tue Jan 13 12:34:56 2015
New Revision: 225813

URL: http://llvm.org/viewvc/llvm-project?rev=225813&view=rev
Log:
When attribute 'optnone' appears on the same declaration with a
conflicting attribute, warn about the conflict and pick a "winning"
attribute to preserve, instead of emitting an error.  This matches the
behavior when the conflicting attributes are on different declarations.

Along the way I discovered that conflicts involving __forceinline were
reported as 'always_inline' (alternate spelling, same attribute) so
fixed that up to report the attribute as spelled in the source.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/SemaCXX/attr-optnone.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=225813&r1=225812&r2=225813&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jan 13 12:34:56 2015
@@ -2009,6 +2009,7 @@ public:
   SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
                                 unsigned AttrSpellingListIndex);
   AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, SourceRange Range,
+                                          IdentifierInfo *Ident,
                                           unsigned AttrSpellingListIndex);
   MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range,
                                 unsigned AttrSpellingListIndex);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=225813&r1=225812&r2=225813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jan 13 12:34:56 2015
@@ -2155,7 +2155,9 @@ static bool mergeDeclAttribute(Sema &S,
                                        AttrSpellingListIndex,
                                        IA->getSemanticSpelling());
   else if (const auto *AA = dyn_cast<AlwaysInlineAttr>(Attr))
-    NewAttr = S.mergeAlwaysInlineAttr(D, AA->getRange(), AttrSpellingListIndex);
+    NewAttr = S.mergeAlwaysInlineAttr(D, AA->getRange(),
+                                      &S.Context.Idents.get(AA->getSpelling()),
+                                      AttrSpellingListIndex);
   else if (const auto *MA = dyn_cast<MinSizeAttr>(Attr))
     NewAttr = S.mergeMinSizeAttr(D, MA->getRange(), AttrSpellingListIndex);
   else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr))

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=225813&r1=225812&r2=225813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Jan 13 12:34:56 2015
@@ -3141,9 +3141,10 @@ static void handleNoDebugAttr(Sema &S, D
 }
 
 AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D, SourceRange Range,
+                                              IdentifierInfo *Ident,
                                               unsigned AttrSpellingListIndex) {
   if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
-    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'always_inline'";
+    Diag(Range.getBegin(), diag::warn_attribute_ignored) << Ident;
     Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
     return nullptr;
   }
@@ -3191,34 +3192,23 @@ OptimizeNoneAttr *Sema::mergeOptimizeNon
 
 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
-  if (checkAttrMutualExclusion<OptimizeNoneAttr>(S, D, Attr))
-    return;
+  if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr(
+          D, Attr.getRange(), Attr.getName(),
+          Attr.getAttributeSpellingListIndex()))
+    D->addAttr(Inline);
+}
 
-  D->addAttr(::new (S.Context)
-             AlwaysInlineAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleMinSizeAttr(Sema &S, Decl *D,
-                              const AttributeList &Attr) {
-  if (checkAttrMutualExclusion<OptimizeNoneAttr>(S, D, Attr))
-    return;
-
-  D->addAttr(::new (S.Context)
-             MinSizeAttr(Attr.getRange(), S.Context,
-                         Attr.getAttributeSpellingListIndex()));
+static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(
+          D, Attr.getRange(), Attr.getAttributeSpellingListIndex()))
+    D->addAttr(MinSize);
 }
 
 static void handleOptimizeNoneAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
-  if (checkAttrMutualExclusion<AlwaysInlineAttr>(S, D, Attr))
-    return;
-  if (checkAttrMutualExclusion<MinSizeAttr>(S, D, Attr))
-    return;
-
-  D->addAttr(::new (S.Context)
-             OptimizeNoneAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
+  if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(
+          D, Attr.getRange(), Attr.getAttributeSpellingListIndex()))
+    D->addAttr(Optnone);
 }
 
 static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {

Modified: cfe/trunk/test/SemaCXX/attr-optnone.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-optnone.cpp?rev=225813&r1=225812&r2=225813&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-optnone.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-optnone.cpp Tue Jan 13 12:34:56 2015
@@ -3,8 +3,8 @@
 int foo() __attribute__((optnone));
 int bar() __attribute__((optnone)) __attribute__((noinline));
 
-int baz() __attribute__((always_inline)) __attribute__((optnone)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
-int quz() __attribute__((optnone)) __attribute__((always_inline)); // expected-error{{'optnone' and 'always_inline' attributes are not compatible}}
+int baz() __attribute__((always_inline)) __attribute__((optnone)); // expected-warning{{'always_inline' attribute ignored}} expected-note{{conflicting attribute is here}}
+int quz() __attribute__((optnone)) __attribute__((always_inline)); // expected-warning{{'always_inline' attribute ignored}} expected-note{{conflicting attribute is here}}
 
 __attribute__((always_inline)) int baz1(); // expected-warning{{'always_inline' attribute ignored}}
 __attribute__((optnone)) int baz1() { return 1; } // expected-note{{conflicting attribute is here}}
@@ -12,8 +12,8 @@ __attribute__((optnone)) int baz1() { re
 __attribute__((optnone)) int quz1(); // expected-note{{conflicting attribute is here}}
 __attribute__((always_inline)) int quz1() { return 1; } // expected-warning{{'always_inline' attribute ignored}}
 
-int bay() __attribute__((minsize)) __attribute__((optnone)); // expected-error{{'minsize' and 'optnone' attributes are not compatible}}
-int quy() __attribute__((optnone)) __attribute__((minsize)); // expected-error{{'optnone' and 'minsize' attributes are not compatible}}
+int bay() __attribute__((minsize)) __attribute__((optnone)); // expected-warning{{'minsize' attribute ignored}} expected-note{{conflicting}}
+int quy() __attribute__((optnone)) __attribute__((minsize)); // expected-warning{{'minsize' attribute ignored}} expected-note{{conflicting}}
 
 __attribute__((minsize)) int bay1(); // expected-warning{{'minsize' attribute ignored}}
 __attribute__((optnone)) int bay1() { return 1; } // expected-note{{conflicting attribute is here}}
@@ -27,8 +27,13 @@ void bay2();
 __attribute__((optnone)) // expected-note 2 {{conflicting}}
 void bay2() {}
 
-__forceinline __attribute__((optnone)) int bax(); // expected-error{{'__forceinline' and 'optnone' attributes are not compatible}}
-__attribute__((optnone)) __forceinline int qux(); // expected-error{{'optnone' and '__forceinline' attributes are not compatible}}
+__forceinline __attribute__((optnone)) int bax(); // expected-warning{{'__forceinline' attribute ignored}} expected-note{{conflicting}}
+__attribute__((optnone)) __forceinline int qux(); // expected-warning{{'__forceinline' attribute ignored}} expected-note{{conflicting}}
+
+__forceinline int bax2(); // expected-warning{{'__forceinline' attribute ignored}}
+__attribute__((optnone)) int bax2() { return 1; } // expected-note{{conflicting}}
+__attribute__((optnone)) int qux2(); // expected-note{{conflicting}}
+__forceinline int qux2() { return 1; } // expected-warning{{'__forceinline' attribute ignored}}
 
 int globalVar __attribute__((optnone)); // expected-warning{{'optnone' attribute only applies to functions}}
 
@@ -50,8 +55,8 @@ int foo2();
 [[clang::optnone]]
 int bar2() __attribute__((noinline));
 
-[[clang::optnone]]
-int baz2() __attribute__((always_inline)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+[[clang::optnone]] // expected-note {{conflicting}}
+int baz2() __attribute__((always_inline)); // expected-warning{{'always_inline' attribute ignored}}
 
 [[clang::optnone]] int globalVar2; //expected-warning{{'optnone' attribute only applies to functions}}
 





More information about the cfe-commits mailing list