https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/85605
>From 5049e0209e240f0f8a3ccb6e248d55d1480b7bad Mon Sep 17 00:00:00 2001 From: Serge Pavlov <sepavl...@gmail.com> Date: Mon, 18 Mar 2024 13:20:15 +0700 Subject: [PATCH 1/4] [clang] Set correct FPOptions if attribute 'optnone' presents Attribute `optnone` must turn off all optimizations including fast-math ones. Actually AST nodes in the 'optnone' function still had fast-math flags. This change implements fixing FP options before function body is parsed. --- clang/include/clang/Basic/LangOptions.h | 11 +++++++++++ clang/include/clang/Sema/Sema.h | 1 + clang/lib/Parse/ParseStmt.cpp | 4 ++++ clang/lib/Sema/SemaDecl.cpp | 10 ++++++++++ clang/test/AST/ast-dump-fpfeatures.cpp | 11 +++++++++++ 5 files changed, 37 insertions(+) diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 08fc706e3cbf74..19c60a8cb5e946 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -842,6 +842,8 @@ class FPOptions { /// Return difference with the given option set. FPOptionsOverride getChangesFrom(const FPOptions &Base) const; + void applyChanges(FPOptionsOverride FPO); + // We can define most of the accessors automatically: #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ TYPE get##NAME() const { \ @@ -923,6 +925,11 @@ class FPOptionsOverride { setAllowFPContractAcrossStatement(); } + void setDisallowOptimizations() { + setFPPreciseEnabled(true); + setDisallowFPContract(); + } + storage_type getAsOpaqueInt() const { return (static_cast<storage_type>(Options.getAsOpaqueInt()) << FPOptions::StorageBitSize) | @@ -979,6 +986,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const return getChangesSlow(Base); } +inline void FPOptions::applyChanges(FPOptionsOverride FPO) { + *this = FPO.applyOverrides(*this); +} + /// Describes the kind of translation unit being processed. enum TranslationUnitKind { /// The translation unit is a complete translation unit. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 95ea5ebc7f1ac1..ccc2ded67589ec 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3222,6 +3222,7 @@ class Sema final { Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D, SkipBodyInfo *SkipBody = nullptr, FnBodyKind BodyKind = FnBodyKind::Other); + void applyFunctionAttributesBeforeParsingBody(Decl *FD); /// Determine whether we can delay parsing the body of a function or /// function template until it is used, assuming we don't care about emitting diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 76a3fa8f2627de..489ae9f167b95d 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -2508,6 +2508,10 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { Sema::PragmaStackSentinelRAII PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod); + // Some function attributes (like OptimizeNoneAttr) affect FP options. + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + Actions.applyFunctionAttributesBeforeParsingBody(Decl); + // Do not enter a scope for the brace, as the arguments are in the same scope // (the function body) as the body itself. Instead, just read the statement // list and put it into a CompoundStmt for safe keeping. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5850cd0ab6b9aa..1f52f5e57e5376 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15919,6 +15919,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, return D; } +void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) { + if (FD && FD->hasAttr<OptimizeNoneAttr>()) { + FPOptionsOverride FPO; + FPO.setDisallowOptimizations(); + CurFPFeatures.applyChanges(FPO); + FpPragmaStack.CurrentValue = + CurFPFeatures.getChangesFrom(FPOptions(LangOpts)); + } +} + /// Given the set of return statements within a function body, /// compute the variables that are subject to the named return value /// optimization. diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp index da0011602a728e..5eda5528c07018 100644 --- a/clang/test/AST/ast-dump-fpfeatures.cpp +++ b/clang/test/AST/ast-dump-fpfeatures.cpp @@ -187,3 +187,14 @@ float func_18(float x, float y) { // CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward // CHECK: ReturnStmt // CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward + +#pragma float_control(precise, off) +__attribute__((optnone)) +float func_19(float x, float y) { + return x + y; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_19 'float (float, float)' +// CHECK: CompoundStmt {{.*}} MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 >From 52755f263b992ba2add370319cea9cb5c5d8cda6 Mon Sep 17 00:00:00 2001 From: Serge Pavlov <sepavl...@gmail.com> Date: Wed, 20 Mar 2024 23:22:49 +0700 Subject: [PATCH 2/4] Support more cases of function body --- clang/lib/Parse/ParseStmt.cpp | 4 ---- clang/lib/Parse/Parser.cpp | 4 ++++ clang/test/AST/ast-dump-fpfeatures.cpp | 30 +++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 489ae9f167b95d..76a3fa8f2627de 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -2508,10 +2508,6 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { Sema::PragmaStackSentinelRAII PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod); - // Some function attributes (like OptimizeNoneAttr) affect FP options. - Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); - Actions.applyFunctionAttributesBeforeParsingBody(Decl); - // Do not enter a scope for the brace, as the arguments are in the same scope // (the function body) as the body itself. Instead, just read the statement // list and put it into a CompoundStmt for safe keeping. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index cc0e41ed221c4f..e4b8757c38f7f4 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1495,6 +1495,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, return Actions.ActOnFinishFunctionBody(Res, nullptr, false); } + // Some function attributes (like OptimizeNoneAttr) affect FP options. + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + Actions.applyFunctionAttributesBeforeParsingBody(Res); + if (Tok.is(tok::kw_try)) return ParseFunctionTryBlock(Res, BodyScope); diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp index 5eda5528c07018..68499539c1ed19 100644 --- a/clang/test/AST/ast-dump-fpfeatures.cpp +++ b/clang/test/AST/ast-dump-fpfeatures.cpp @@ -1,10 +1,10 @@ // Test without serialization: -// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -ast-dump %s \ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -fcxx-exceptions -ast-dump %s \ // RUN: | FileCheck --strict-whitespace %s // Test with serialization: -// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -o %t %s -// RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux -include-pch %t -ast-dump-all /dev/null \ +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -fcxx-exceptions -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux -include-pch %t -fcxx-exceptions -ast-dump-all /dev/null \ // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \ // RUN: | FileCheck --strict-whitespace %s @@ -189,6 +189,7 @@ float func_18(float x, float y) { // CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward #pragma float_control(precise, off) + __attribute__((optnone)) float func_19(float x, float y) { return x + y; @@ -198,3 +199,26 @@ float func_19(float x, float y) { // CHECK: CompoundStmt {{.*}} MathErrno=1 // CHECK: ReturnStmt // CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +__attribute__((optnone)) +float func_20(float x, float y) try { + return x + y; +} catch (...) { + return 1.0; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_20 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +struct C21 { + C21(float x, float y); + float member; +}; + +__attribute__((optnone)) C21::C21(float x, float y) : member(x + y) {} + +// CHECK-LABEL: CXXConstructorDecl {{.*}} C21 'void (float, float)' +// CHECK: CXXCtorInitializer {{.*}} 'member' 'float' +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 >From f6f45b61c3cc65ca064c117ad3cefcce87ee8bd1 Mon Sep 17 00:00:00 2001 From: Serge Pavlov <sepavl...@gmail.com> Date: Sun, 24 Mar 2024 01:50:02 +0700 Subject: [PATCH 3/4] Extend the solution for more use cases --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 5 ++++ clang/lib/Parse/ParseObjc.cpp | 3 +++ clang/lib/Parse/ParseTemplate.cpp | 4 ++++ clang/lib/Sema/SemaDecl.cpp | 4 ++++ clang/test/AST/ast-dump-fpfeatures.cpp | 27 +++++++++++++++++++++ clang/test/AST/ast-dump-fpfeatures.m | 29 +++++++++++++++++++++++ clang/test/AST/ast-dump-late-parsing.cpp | 24 +++++++++++++++++++ 7 files changed, 96 insertions(+) create mode 100644 clang/test/AST/ast-dump-fpfeatures.m create mode 100644 clang/test/AST/ast-dump-late-parsing.cpp diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index d790060c17c049..222659e7fc1505 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -559,6 +559,11 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { // to be re-used for method bodies as well. ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); + + // Some function attributes (like OptimizeNoneAttr) affect FP options. + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + Actions.applyFunctionAttributesBeforeParsingBody(LM.D); + Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); if (Tok.is(tok::kw_try)) { diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 88bab0eb27a3ed..929b50da302a1f 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -3736,6 +3736,9 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { ParseScope BodyScope(this, (parseMethod ? Scope::ObjCMethodScope : 0) | Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); + // Some function attributes (like OptimizeNoneAttr) affect FP options. + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + Actions.applyFunctionAttributesBeforeParsingBody(LM.D); // Tell the actions module that we have entered a method or c-function definition // with the specified Declarator for the method/function. diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index d4897f8f66072e..d7ab8020874d44 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1650,6 +1650,10 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { // Recreate the containing function DeclContext. Sema::ContextRAII FunctionSavedContext(Actions, FunD->getLexicalParent()); + // Some function attributes (like OptimizeNoneAttr) affect FP options. + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + Actions.applyFunctionAttributesBeforeParsingBody(LPT.D); + Actions.ActOnStartOfFunctionDef(getCurScope(), FunD); if (Tok.is(tok::kw_try)) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1f52f5e57e5376..967767abf52d5a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15920,6 +15920,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, } void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) { + if (!FD || FD->isInvalidDecl()) + return; + if (auto *TD = dyn_cast<FunctionTemplateDecl>(FD)) + FD = TD->getTemplatedDecl(); if (FD && FD->hasAttr<OptimizeNoneAttr>()) { FPOptionsOverride FPO; FPO.setDisallowOptimizations(); diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp index 68499539c1ed19..68144e31a93043 100644 --- a/clang/test/AST/ast-dump-fpfeatures.cpp +++ b/clang/test/AST/ast-dump-fpfeatures.cpp @@ -214,11 +214,38 @@ float func_20(float x, float y) try { struct C21 { C21(float x, float y); + __attribute__((optnone)) float a_method(float x, float y) { + return x * y; + } float member; }; +// CHECK-LABEL: CXXMethodDecl {{.*}} a_method 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '*' ConstRoundingMode=downward MathErrno=1 + __attribute__((optnone)) C21::C21(float x, float y) : member(x + y) {} // CHECK-LABEL: CXXConstructorDecl {{.*}} C21 'void (float, float)' // CHECK: CXXCtorInitializer {{.*}} 'member' 'float' // CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +template <typename T> +__attribute__((optnone)) T func_22(T x, T y) { + return x + y; +} + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_22 +// CHECK: FunctionDecl {{.*}} func_22 'T (T, T)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} '+' ConstRoundingMode=downward MathErrno=1 +// CHECK: FunctionDecl {{.*}} func_22 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +float func_23(float x, float y) { + return func_22(x, y); +} \ No newline at end of file diff --git a/clang/test/AST/ast-dump-fpfeatures.m b/clang/test/AST/ast-dump-fpfeatures.m new file mode 100644 index 00000000000000..cf77529a756811 --- /dev/null +++ b/clang/test/AST/ast-dump-fpfeatures.m @@ -0,0 +1,29 @@ +// Test without serialization: +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -ast-dump %s \ +// RUN: | FileCheck --strict-whitespace %s + +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -o %t %s +// RUN: %clang_cc1 -x objective-c -triple x86_64-pc-linux -include-pch %t -ast-dump-all /dev/null \ +// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace %s + + +@interface Adder +- (float) sum: (float)x with: (float)y __attribute((optnone)); +@end + +#pragma float_control(precise, off) + +@implementation Adder +- (float) sum: (float)x with: (float)y __attribute((optnone)) { + return x + y; +} + +@end + +// CHECK-LABEL: ObjCImplementationDecl {{.*}} Adder +// CHECK: ObjCMethodDecl {{.*}} - sum:with: 'float' +// CHECK: CompoundStmt {{.*}} MathErrno=1 +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' MathErrno=1 diff --git a/clang/test/AST/ast-dump-late-parsing.cpp b/clang/test/AST/ast-dump-late-parsing.cpp new file mode 100644 index 00000000000000..760664efc5f142 --- /dev/null +++ b/clang/test/AST/ast-dump-late-parsing.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -ast-dump %s \ +// RUN: | FileCheck %s + +#pragma STDC FENV_ROUND FE_DOWNWARD +#pragma float_control(precise, off) + +template <typename T> +__attribute__((optnone)) T func_22(T x, T y) { + return x + y; +} + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_22 +// CHECK: FunctionDecl {{.*}} func_22 'T (T, T)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} '+' ConstRoundingMode=downward MathErrno=1 +// CHECK: FunctionDecl {{.*}} func_22 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +float func_23(float x, float y) { + return func_22(x, y); +} >From 1b7516342e7363dc0d74efd9587b7e4fcd5a13c9 Mon Sep 17 00:00:00 2001 From: Serge Pavlov <sepavl...@gmail.com> Date: Sun, 24 Mar 2024 12:25:27 +0700 Subject: [PATCH 4/4] Set FP features in Sema methods --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 3 --- clang/lib/Parse/ParseObjc.cpp | 2 -- clang/lib/Parse/ParseTemplate.cpp | 4 ---- clang/lib/Parse/Parser.cpp | 2 -- clang/lib/Sema/SemaDecl.cpp | 5 +++++ clang/lib/Sema/SemaDeclObjC.cpp | 4 ++++ 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 222659e7fc1505..27336b1b415a86 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -559,10 +559,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { // to be re-used for method bodies as well. ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); - - // Some function attributes (like OptimizeNoneAttr) affect FP options. Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); - Actions.applyFunctionAttributesBeforeParsingBody(LM.D); Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 929b50da302a1f..74a683a0c43293 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -3736,9 +3736,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { ParseScope BodyScope(this, (parseMethod ? Scope::ObjCMethodScope : 0) | Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); - // Some function attributes (like OptimizeNoneAttr) affect FP options. Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); - Actions.applyFunctionAttributesBeforeParsingBody(LM.D); // Tell the actions module that we have entered a method or c-function definition // with the specified Declarator for the method/function. diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index d7ab8020874d44..d4897f8f66072e 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1650,10 +1650,6 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { // Recreate the containing function DeclContext. Sema::ContextRAII FunctionSavedContext(Actions, FunD->getLexicalParent()); - // Some function attributes (like OptimizeNoneAttr) affect FP options. - Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); - Actions.applyFunctionAttributesBeforeParsingBody(LPT.D); - Actions.ActOnStartOfFunctionDef(getCurScope(), FunD); if (Tok.is(tok::kw_try)) { diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index e4b8757c38f7f4..dcc98efc74aef3 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1495,9 +1495,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, return Actions.ActOnFinishFunctionBody(Res, nullptr, false); } - // Some function attributes (like OptimizeNoneAttr) affect FP options. Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); - Actions.applyFunctionAttributesBeforeParsingBody(Res); if (Tok.is(tok::kw_try)) return ParseFunctionTryBlock(Res, BodyScope); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 967767abf52d5a..ac7c1bae397f7e 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15908,6 +15908,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, FD->setInvalidDecl(); return D; } + + // Some function attributes (like OptimizeNoneAttr) need actions before + // parsing body started. + applyFunctionAttributesBeforeParsingBody(D); + // We want to attach documentation to original Decl (which might be // a function template). ActOnDocumentableDecl(D); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 94a245f0f905f3..a6677fae242c6a 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -494,6 +494,10 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { } } } + + // Some function attributes (like OptimizeNoneAttr) need actions before + // parsing body started. + applyFunctionAttributesBeforeParsingBody(D); } namespace { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits