Support strlen() and __builtin_strlen() as constant expressions with

the call argument is a string literal. Fixes
<rdar://problem/8413477>.

llvm-svn: 113580
This commit is contained in:
Douglas Gregor 2010-09-10 06:27:15 +00:00
parent 9c8a97ce0a
commit 6a6dac2fbf
2 changed files with 22 additions and 0 deletions

View File

@ -1159,6 +1159,24 @@ bool IntExprEvaluator::VisitCallExpr(CallExpr *E) {
case Builtin::BI__builtin_expect:
return Visit(E->getArg(0));
case Builtin::BIstrlen:
case Builtin::BI__builtin_strlen:
// As an extension, we support strlen() and __builtin_strlen() as constant
// expressions when the argument is a string literal.
if (StringLiteral *S
= dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenImpCasts())) {
// The string literal may have embedded null characters. Find the first
// one and truncate there.
llvm::StringRef Str = S->getString();
llvm::StringRef::size_type Pos = Str.find(0);
if (Pos != llvm::StringRef::npos)
Str = Str.substr(0, Pos);
return Success(Str.size(), E);
}
return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
}
}

View File

@ -50,3 +50,7 @@ int h0 = __builtin_types_compatible_p(int, float);
//int h2 = __builtin_expect(0, 0);
extern long int bi0;
extern __typeof__(__builtin_expect(0, 0)) bi0;
// Strings
int array1[__builtin_strlen("ab\0cd")];
int array2[(sizeof(array1)/sizeof(int)) == 2? 1 : -1];