Page MenuHomePhabricator

[Clang] Interaction of FP pragmas and function template instantiation
Needs ReviewPublic

Authored by sepavloff on Aug 3 2022, 11:30 PM.

Details

Summary

C standard defines set of pragmas that modify code generation for
operations on floating point values. In C++ code may be obtained using
template instantiation and from practical viewpoint it is necessary to
have possibility to modify code generation in this case as well. This
change implements interaction of FP pragmas with function template
instantiations.

If a function template contains a floating-point control pragma, the
latter is a part of template definition and presents in all
instantiations. If a pragma in placed outside any function it acts on
function templates in the same way as on functions. For the task of
function instantiation such pragma is equivalent to the same pragma put
at the beginning of all affected function bodies.

In the case is explicit instantiation there is apparent connection
between a point in source code and instantiated function. It can
support interaction of pragmas that act in that point. For example, in
the code:

#pragma STDC FENV_ROUND FE_DOWNWARD
template float func_05<short>(float, float);

the instantiated function is created with the specified constant
rounding mode. The effect is same as if the template pattern were
textually inserted into the code with needed replacements.

Implicit instantiations occur with FP options deduced from LangOpts.
They have no apparent connection to source code and are not influenced
by FP pragmas.

Diff Detail

Event Timeline

sepavloff created this revision.Aug 3 2022, 11:30 PM
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: martong. · View Herald Transcript
sepavloff requested review of this revision.Aug 3 2022, 11:30 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2022, 11:30 PM
martong removed a subscriber: martong.Aug 4 2022, 2:12 AM

In the case is explicit instantiation there is apparent connection
between a point in source code and instantiated function. It can
support interaction of pragmas that act in that point. For example, in
the code:

#pragma STDC FENV_ROUND FE_DOWNWARD
template float func_05<short>(float, float);

the instantiated function is created with the specified constant
rounding mode. The effect is same as if the template pattern were
textually inserted into the code with needed replacements.

These pragmas aren't currently part of the C++ standard, but I strongly doubt the C++ standards committee would choose to do this. You would end up with undefined behavior due to mismatched definitions, if the template is implicitly instantiated elsewhere.

The "obvious" rule here is just to always use the pragma in effect at the point the template body is written.

I completely agree with Eli.

In the case is explicit instantiation there is apparent connection
between a point in source code and instantiated function. It can
support interaction of pragmas that act in that point. For example, in
the code:

#pragma STDC FENV_ROUND FE_DOWNWARD
template float func_05<short>(float, float);

the instantiated function is created with the specified constant
rounding mode. The effect is same as if the template pattern were
textually inserted into the code with needed replacements.

These pragmas aren't currently part of the C++ standard, but I strongly doubt the C++ standards committee would choose to do this.

This is an attempt to implement the interaction as proposed in the review of D129464. It is, of course, an extension, which may be convenient but nothing serious would happen if it is not implemented.

You would end up with undefined behavior due to mismatched definitions, if the template is implicitly instantiated elsewhere.

Indeed, it makes the solution fragile.

The "obvious" rule here is just to always use the pragma in effect at the point the template body is written.

Sure, it is already works in this way.