Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2819,34 +2819,35 @@ class Sema final : public SemaBase {

/// BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr
/// TheCall is a constant expression.
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result);
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum,
llvm::APSInt &Result);

/// BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr
/// TheCall is a constant expression in the range [Low, High].
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High,
bool RangeIsError = true);
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low,
int High, bool RangeIsError = true);

/// BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr
/// TheCall is a constant expression is a multiple of Num..
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum,
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum,
unsigned Multiple);

/// BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a
/// constant expression representing a power of 2.
bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum);
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum);

/// BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is
/// a constant expression representing an arbitrary byte value shifted left by
/// a multiple of 8 bits.
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum,
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum,
unsigned ArgBits);

/// BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of
/// TheCall is a constant expression representing either a shifted byte value,
/// or a value of the form 0x??FF (i.e. a member of the arithmetic progression
/// 0x00FF, 0x01FF, ..., 0xFFFF). This strange range check is needed for some
/// Arm MVE intrinsics.
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum,
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum,
unsigned ArgBits);

/// Checks that a call expression's argument count is at least the desired
Expand Down
34 changes: 18 additions & 16 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5618,8 +5618,8 @@ ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {
if (Arg->isTypeDependent() || Arg->isValueDependent())
continue;

std::optional<llvm::APSInt> Result;
if (!(Result = Arg->getIntegerConstantExpr(Context)))
std::optional<llvm::APSInt> Result = Arg->getIntegerConstantExpr(Context);
if (!Result)
return ExprError(Diag(TheCall->getBeginLoc(),
diag::err_shufflevector_nonconstant_argument)
<< Arg->getSourceRange());
Expand Down Expand Up @@ -5886,23 +5886,26 @@ bool Sema::BuiltinOSLogFormat(CallExpr *TheCall) {
return false;
}

bool Sema::BuiltinConstantArg(CallExpr *TheCall, int ArgNum,
bool Sema::BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum,
llvm::APSInt &Result) {
Expr *Arg = TheCall->getArg(ArgNum);
DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());

if (Arg->isTypeDependent() || Arg->isValueDependent()) return false;
if (Arg->isTypeDependent() || Arg->isValueDependent())
return false;

std::optional<llvm::APSInt> R;
if (!(R = Arg->getIntegerConstantExpr(Context)))
std::optional<llvm::APSInt> R = Arg->getIntegerConstantExpr(Context);
if (!R) {
auto *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
auto *FDecl = cast<FunctionDecl>(DRE->getDecl());
return Diag(TheCall->getBeginLoc(), diag::err_constant_integer_arg_type)
<< FDecl->getDeclName() << Arg->getSourceRange();
}
Result = *R;

return false;
}

bool Sema::BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low,
bool Sema::BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low,
int High, bool RangeIsError) {
if (isConstantEvaluatedContext())
return false;
Expand Down Expand Up @@ -5933,7 +5936,7 @@ bool Sema::BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low,
return false;
}

bool Sema::BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum,
bool Sema::BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum,
unsigned Num) {
llvm::APSInt Result;

Expand All @@ -5953,7 +5956,7 @@ bool Sema::BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum,
return false;
}

bool Sema::BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum) {
bool Sema::BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum) {
llvm::APSInt Result;

// We can't check the value of a dependent argument.
Expand All @@ -5965,9 +5968,7 @@ bool Sema::BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum) {
if (BuiltinConstantArg(TheCall, ArgNum, Result))
return true;

// Bit-twiddling to test for a power of 2: for x > 0, x & (x-1) is zero if
// and only if x is a power of 2.
if (Result.isStrictlyPositive() && (Result & (Result - 1)) == 0)
if (Result.isPowerOf2())
return false;

return Diag(TheCall->getBeginLoc(), diag::err_argument_not_power_of_2)
Expand Down Expand Up @@ -5996,7 +5997,7 @@ static bool IsShiftedByte(llvm::APSInt Value) {
}
}

bool Sema::BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum,
bool Sema::BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum,
unsigned ArgBits) {
llvm::APSInt Result;

Expand All @@ -6020,7 +6021,8 @@ bool Sema::BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum,
<< Arg->getSourceRange();
}

bool Sema::BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum,
bool Sema::BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall,
unsigned ArgNum,
unsigned ArgBits) {
llvm::APSInt Result;

Expand Down
Loading