================
@@ -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

Reply via email to