Skip to content

Commit

Permalink
[clang] Do not clear FP pragma stack when instantiating functions (#7…
Browse files Browse the repository at this point in the history
…0646)

When instantiation function, a call to Sema::resetFPOption was used to
set the FP options associated with AST node. However this function also
cleared FP pragma stack, and it is incorrect. Template instantiation
takes place on AST representation and semantic information like the FP
pragma stack should not affect it. This was a reason for miscompilation
in some cases.

To make the Sema interface more consistent, now `resetFPOptions` does
not clear FP pragma stack anymore. It is cleared in
`FpPragmaStackSaveRAII`, which is used in parsing only.

This change must fix #69717
(Problems with float_control pragma stack in Clang 17.x).
  • Loading branch information
spavloff committed Nov 13, 2023
1 parent a699ab5 commit f6f625f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
7 changes: 5 additions & 2 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,9 +710,13 @@ class Sema final {
return result;
}

// Saves the current floating-point pragma stack and clear it in this Sema.
class FpPragmaStackSaveRAII {
public:
FpPragmaStackSaveRAII(Sema &S) : S(S), SavedStack(S.FpPragmaStack) {}
FpPragmaStackSaveRAII(Sema &S)
: S(S), SavedStack(std::move(S.FpPragmaStack)) {
S.FpPragmaStack.Stack.clear();
}
~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }

private:
Expand All @@ -722,7 +726,6 @@ class Sema final {

void resetFPOptions(FPOptions FPO) {
CurFPFeatures = FPO;
FpPragmaStack.Stack.clear();
FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
}

Expand Down
17 changes: 17 additions & 0 deletions clang/test/Sema/PR69717.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %clang_cc1 -verify -fsyntax-only %s
// expected-no-diagnostics

// Testcase for https://github.com/llvm/llvm-project/issues/69717

#pragma float_control(precise, on, push)

template<typename T>
constexpr T multi(T x, T y) {
return x * y;
}

int multi_i(int x, int y) {
return multi<int>(x, y);
}

#pragma float_control(pop)

0 comments on commit f6f625f

Please sign in to comment.