diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8348,6 +8348,9 @@ def err_overflow_builtin_ext_int_max_size : Error< "__builtin_mul_overflow does not support signed _ExtInt operands of more " "than %0 bits">; +def err_overflow_builtin_special_combination_max_size : Error< + "__builtin_mul_overflow does not suport unsigned overflow check after convention " + "more than %0 bits">; def err_atomic_load_store_uses_lib : Error< "atomic %select{load|store}0 requires runtime support that is not " diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -328,6 +328,20 @@ // Disallow signed ExtIntType args larger than 128 bits to mul function until // we improve backend support. if (BuiltinID == Builtin::BI__builtin_mul_overflow) { + const auto LeftTy = TheCall->getArg(0)->getType(); + const auto RightTy = TheCall->getArg(1)->getType(); + const auto ResultPointeeTy = TheCall->getArg(2)->getType()->getPointeeType(); + // Input combination below will also emit an integer value larger than + // 128 bits in the backend, disallow same as above. + if (!ResultTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(ResultTy) >= 128 && + (LeftTy->isSignedIntegerType() || RightTy->isSignedIntegerType()) && + (S.getASTContext().getIntWidth(LeftTy) + S.getASTContext().getIntWidth(RightTy)) > 128 && + ) { + return S.Diag(TheCall->getArg(0)->getBeginLoc(), + diag::err_overflow_builtin_special_combination_max_size) + << 127; + } for (unsigned I = 0; I < 3; ++I) { const auto Arg = TheCall->getArg(I); // Third argument will be a pointer. diff --git a/clang/test/Sema/builtins-overflow.c b/clang/test/Sema/builtins-overflow.c --- a/clang/test/Sema/builtins-overflow.c +++ b/clang/test/Sema/builtins-overflow.c @@ -38,4 +38,10 @@ _ExtInt(129) result; _Bool status = __builtin_mul_overflow(x, y, &result); // expected-error {{__builtin_mul_overflow does not support signed _ExtInt operands of more than 128 bits}} } + { + _ExtInt(128) x = 1; + _ExtInt(128) y = 1; + unsigned _ExtInt(128) result; + _Bool status = __builtin_mul_overflow(x, y, &result); // expected-error {{__builtin_mul_overflow does not support special combination operands (signed, signed, unsigned*) of more than 64 bits}} + } }