This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Reset FP options before function instantiations
ClosedPublic

Authored by sepavloff on Feb 2 2023, 10:23 PM.

Details

Summary

Previously function template instantiations occurred with FP options
that were in effect at the end of translation unit. It was a problem
for late template parsing as these FP options were used as attributes of
AST nodes and may result in crash. To fix it FP options are set to the
state of the point of template definition.

Diff Detail

Event Timeline

sepavloff created this revision.Feb 2 2023, 10:23 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2023, 10:23 PM
sepavloff requested review of this revision.Feb 2 2023, 10:23 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2023, 10:23 PM

Using the FPOptions from the beginning of the file doesn't seem much better than the FPOptions at the end of the file. Don't we want to use the FPOptions from the point of definition of the template?

sepavloff updated this revision to Diff 527800.Jun 2 2023, 4:07 AM

Use FPOptions from the place where template is defined rather than default

sepavloff edited the summary of this revision. (Show Details)Jun 2 2023, 6:24 AM
This revision is now accepted and ready to land.Jun 21 2023, 11:27 AM
rjmccall added inline comments.Jun 21 2023, 11:38 AM
clang/lib/Parse/ParseTemplate.cpp
1736 ↗(On Diff #527800)

Ah, is this bug specific to the MSVC-compatible template logic?

sepavloff added inline comments.Jun 21 2023, 10:30 PM
clang/lib/Parse/ParseTemplate.cpp
1736 ↗(On Diff #527800)

Exactly. This is MSVC bug-or-feature.

Hmm. Why are we clearing the FP pragma stack instead of saving the old context onto it and then restoring after instantiation? I don't think semantic analysis ever depends on enclosing members of the stack, does it?

Clearing the entire stack might not matter much if we're at the end of the translation unit, which is the normal time to instantiate things, but it would matter if we're eagerly instantiating within the translation unit, which we have to do for various reasons, including explicit instantiation and constexpr.

Hmm. Why are we clearing the FP pragma stack instead of saving the old context onto it and then restoring after instantiation? I don't think semantic analysis ever depends on enclosing members of the stack, does it?

It shouldn't but the function body may contain pragmas and in the case of errors we could have weird behavior. Anyway, parsing in this case occurs at the end of translation unit, so it should be safe to clear pragma stack.

Clearing the entire stack might not matter much if we're at the end of the translation unit, which is the normal time to instantiate things, but it would matter if we're eagerly instantiating within the translation unit, which we have to do for various reasons, including explicit instantiation and constexpr.

Explicit instantiation performs late parsing at the end of translation unit, just as implicit one. Constexpr functions are parsed as usualy, at the point of definition (see Sema::canDelayFunctionBody). It seems late parsing always occurs at the end of TU.

This revision was landed with ongoing or failed builds.Jun 28 2023, 6:13 AM
This revision was automatically updated to reflect the committed changes.

Hi, the following assertion is getting tripped on AIX:

Assertion failed: *FpPragmaCurrentValue == SemaObj->FpPragmaStack.DefaultValue && "Expected a default pragma float_control value", file  /scratch/powerllvm/powerllvm_env/aix-ppc64/clang-ppc64-aix/llvm-project/clang/lib/Serialization/ASTReader.cpp, line 8150, void clang::ASTReader::UpdateSema()()

https://lab.llvm.org/buildbot/#/builders/214/builds/8309/steps/6/logs/FAIL__Clang__late-parsed-instantiations_cpp

Hi, the following assertion is getting tripped on AIX:

Assertion failed: *FpPragmaCurrentValue == SemaObj->FpPragmaStack.DefaultValue && "Expected a default pragma float_control value", file  /scratch/powerllvm/powerllvm_env/aix-ppc64/clang-ppc64-aix/llvm-project/clang/lib/Serialization/ASTReader.cpp, line 8150, void clang::ASTReader::UpdateSema()()

https://lab.llvm.org/buildbot/#/builders/214/builds/8309/steps/6/logs/FAIL__Clang__late-parsed-instantiations_cpp

This crash is observed only on clang-ppc64-aix buildbot. I created an issue for it: https://github.com/llvm/llvm-project/issues/63704 and xfailed the test on this platform: https://reviews.llvm.org/rGd4a5673addd6 .

During our regular snapshot testing, we've hit this in Gentoo on 32-bit Linux x86: https://github.com/llvm/llvm-project/issues/63704#issuecomment-1631791518.