diff options
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 6b60312..6428be1 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8473,6 +8473,9 @@ static void CheckFormatString( llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers); +static const Expr *maybeConstEvalStringLiteral(ASTContext &Context, + const Expr *E); + // Determine if an expression is a string literal or constant string. // If this function returns false on the arguments to a function expecting a // format string, we will usually need to emit a warning. @@ -8713,7 +8716,11 @@ tryAgain: } } } - + if (const auto *SLE = maybeConstEvalStringLiteral(S.Context, E)) + return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg, + Type, CallType, /*InFunctionCall*/ false, + CheckedVarArgs, UncoveredArg, Offset, + IgnoreStringsWithoutSpecifiers); return SLCT_NotALiteral; } case Stmt::ObjCMessageExprClass: { @@ -8823,6 +8830,20 @@ tryAgain: } } +// If this expression can be evaluated at compile-time, +// check if the result is a StringLiteral and return it +// otherwise return nullptr +static const Expr *maybeConstEvalStringLiteral(ASTContext &Context, + const Expr *E) { + Expr::EvalResult Result; + if (E->EvaluateAsRValue(Result, Context) && Result.Val.isLValue()) { + const auto *LVE = Result.Val.getLValueBase().dyn_cast<const Expr *>(); + if (isa_and_nonnull<StringLiteral>(LVE)) + return LVE; + } + return nullptr; +} + Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) { return llvm::StringSwitch<FormatStringType>(Format->getType()->getName()) .Case("scanf", FST_Scanf) |