diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2255,6 +2255,13 @@ let Documentation = [OptnoneDocs]; } +def NeverOptimizeNone : InheritableAttr { + // This attribute has no spellings as it is only ever created implicitly. + let Spellings = []; + let Subjects = SubjectList<[Function]>; + let Documentation = [Undocumented]; +} + def Overloadable : Attr { let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1928,7 +1928,8 @@ ShouldAddOptNone &= !D->hasAttr(); // Add optnone, but do so only if the function isn't always_inline. - if ((ShouldAddOptNone || D->hasAttr()) && + if (!D->hasAttr() && + (ShouldAddOptNone || D->hasAttr()) && !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { B.addAttribute(llvm::Attribute::OptimizeNone); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -8519,6 +8519,9 @@ case ParsedAttr::AT_OptimizeNone: handleOptimizeNoneAttr(S, D, AL); break; + case ParsedAttr::AT_NeverOptimizeNone: + handleSimpleAttribute(S, D, AL); + break; case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break;