================
@@ -20911,9 +20911,28 @@ static bool actOnOMPReductionKindClause(
Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
break;
case BO_Mul:
+ // '*' reduction op - initializer is '1'.
+ // For C++ class types (e.g. std::complex) the OpenMP built-in
+ // reduction identifiers are an extension: the standard only defines
+ // identities for arithmetic (and, in Clang, _Complex) types. Without
+ // an explicit initializer the private copy would be value-initialized,
+ // which yields the *additive* identity (e.g. std::complex(0,0)) and is
+ // wrong for multiplication. Initialize from the integer literal '1'
+ // instead and let the converting constructor build the multiplicative
+ // identity (e.g. std::complex(1) == (1,0)). If the type is not
+ // constructible from '1', AddInitializerToDecl below diagnoses it and
+ // the list item is dropped, so we never silently miscompile.
+ // Note: BO_Add deliberately keeps relying on value-initialization for
+ // class types, because there the (0,0) default is the correct additive
+ // identity for the common case; only '*' needs this special handling.
+ if (Type->isScalarType() || Type->isAnyComplexType() ||
+ (S.getLangOpts().CPlusPlus && Type->isRecordType())) {
+ Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
+ }
----------------
dmikushin wrote:
Done, thanks. Now probing with `InitializationSequence` first and only using 1
when copy-init from it is viable; otherwise the initializer is left empty and
we fall back to the default (value-init) behavior, so such code keeps compiling
as before. Tests updated.
https://github.com/llvm/llvm-project/pull/202292
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits