diff options
author | OverMighty <its.overmighty@gmail.com> | 2024-03-21 16:33:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-21 09:33:16 -0700 |
commit | c1c2551a2876f536b5a06f48fa809aeedbc3d7ba (patch) | |
tree | 425b854ed4c1c503ee07d679f418036593d6a6c8 /clang/lib/Sema/SemaChecking.cpp | |
parent | 9a87d4d546a4382879b1beb96687acbad0ef4cc0 (diff) | |
download | llvm-c1c2551a2876f536b5a06f48fa809aeedbc3d7ba.zip llvm-c1c2551a2876f536b5a06f48fa809aeedbc3d7ba.tar.gz llvm-c1c2551a2876f536b5a06f48fa809aeedbc3d7ba.tar.bz2 |
[clang] Implement __builtin_{clzg,ctzg} (#83431)
Fixes #83075, fixes #83076.
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ef3ab16..246e357 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2399,6 +2399,48 @@ static bool SemaBuiltinPopcountg(Sema &S, CallExpr *TheCall) { return false; } +/// Checks that __builtin_{clzg,ctzg} was called with a first argument, which is +/// an unsigned integer, and an optional second argument, which is promoted to +/// an 'int'. +static bool SemaBuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) { + if (checkArgCountRange(S, TheCall, 1, 2)) + return true; + + ExprResult Arg0Res = S.DefaultLvalueConversion(TheCall->getArg(0)); + if (Arg0Res.isInvalid()) + return true; + + Expr *Arg0 = Arg0Res.get(); + TheCall->setArg(0, Arg0); + + QualType Arg0Ty = Arg0->getType(); + + if (!Arg0Ty->isUnsignedIntegerType()) { + S.Diag(Arg0->getBeginLoc(), diag::err_builtin_invalid_arg_type) + << 1 << /*unsigned integer ty*/ 7 << Arg0Ty; + return true; + } + + if (TheCall->getNumArgs() > 1) { + ExprResult Arg1Res = S.UsualUnaryConversions(TheCall->getArg(1)); + if (Arg1Res.isInvalid()) + return true; + + Expr *Arg1 = Arg1Res.get(); + TheCall->setArg(1, Arg1); + + QualType Arg1Ty = Arg1->getType(); + + if (!Arg1Ty->isSpecificBuiltinType(BuiltinType::Int)) { + S.Diag(Arg1->getBeginLoc(), diag::err_builtin_invalid_arg_type) + << 2 << /*'int' ty*/ 8 << Arg1Ty; + return true; + } + } + + return false; +} + ExprResult Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall) { @@ -3187,6 +3229,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (SemaBuiltinPopcountg(*this, TheCall)) return ExprError(); break; + case Builtin::BI__builtin_clzg: + case Builtin::BI__builtin_ctzg: + if (SemaBuiltinCountZeroBitsGeneric(*this, TheCall)) + return ExprError(); + break; } if (getLangOpts().HLSL && CheckHLSLBuiltinFunctionCall(BuiltinID, TheCall)) |