Skip to content

Commit 380e10a

Browse files
tbaederrmahesh-attarde
authored andcommitted
[clang][bytecode] Use in Expr::tryEvaluateStrLen() (llvm#149677)
Fixes llvm#138475
1 parent cdc442e commit 380e10a

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

clang/lib/AST/ByteCode/Context.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,43 @@ bool Context::evaluateCharRange(State &Parent, const Expr *SizeExpr,
235235
return evaluateStringRepr(Parent, SizeExpr, PtrExpr, Result);
236236
}
237237

238+
bool Context::evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result) {
239+
assert(Stk.empty());
240+
Compiler<EvalEmitter> C(*this, *P, Parent, Stk);
241+
242+
auto PtrRes = C.interpretAsPointer(E, [&](const Pointer &Ptr) {
243+
const Descriptor *FieldDesc = Ptr.getFieldDesc();
244+
if (!FieldDesc->isPrimitiveArray())
245+
return false;
246+
247+
unsigned N = Ptr.getNumElems();
248+
if (Ptr.elemSize() == 1) {
249+
Result = strnlen(reinterpret_cast<const char *>(Ptr.getRawAddress()), N);
250+
return Result != N;
251+
}
252+
253+
PrimType ElemT = FieldDesc->getPrimType();
254+
Result = 0;
255+
for (unsigned I = Ptr.getIndex(); I != N; ++I) {
256+
INT_TYPE_SWITCH(ElemT, {
257+
auto Elem = Ptr.atIndex(I).deref<T>();
258+
if (Elem.isZero())
259+
return true;
260+
++Result;
261+
});
262+
}
263+
// We didn't find a 0 byte.
264+
return false;
265+
});
266+
267+
if (PtrRes.isInvalid()) {
268+
C.cleanup();
269+
Stk.clear();
270+
return false;
271+
}
272+
return true;
273+
}
274+
238275
const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
239276

240277
static PrimType integralTypeToPrimTypeS(unsigned BitWidth) {

clang/lib/AST/ByteCode/Context.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ class Context final {
6666
bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
6767
const Expr *PtrExpr, std::string &Result);
6868

69+
/// Evalute \param E and if it can be evaluated to a string literal,
70+
/// run strlen() on it.
71+
bool evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result);
72+
6973
/// Returns the AST context.
7074
ASTContext &getASTContext() const { return Ctx; }
7175
/// Returns the language options.

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18184,6 +18184,10 @@ bool Expr::EvaluateCharRangeAsString(APValue &Result,
1818418184
bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const {
1818518185
Expr::EvalStatus Status;
1818618186
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18187+
18188+
if (Info.EnableNewConstInterp)
18189+
return Info.Ctx.getInterpContext().evaluateStrlen(Info, this, Result);
18190+
1818718191
return EvaluateBuiltinStrLen(this, Result, Info);
1818818192
}
1818918193

clang/test/Sema/warn-fortify-source.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify
44
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
55

6+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -fexperimental-new-constant-interpreter
7+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS -fexperimental-new-constant-interpreter
8+
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -fexperimental-new-constant-interpreter
9+
// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS -fexperimental-new-constant-interpreter
10+
611
typedef unsigned long size_t;
712

813
#ifdef __cplusplus

0 commit comments

Comments
 (0)