diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-10 06:27:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-10 06:27:15 +0000 |
commit | 5726d405e71f11feaaf0c8f518abe26e909537a4 (patch) | |
tree | 6cea51e0bebf26f8b1f1703b6c7282fa41b1febd | |
parent | 942e24d0ca23ebd9a8d8a180d35dad237235b94a (diff) |
Support strlen() and __builtin_strlen() as constant expressions with
the call argument is a string literal. Fixes
<rdar://problem/8413477>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113580 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/ExprConstant.cpp | 18 | ||||
-rw-r--r-- | test/Sema/constant-builtins-2.c | 4 |
2 files changed, 22 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 04aea9e9b9..7736581738 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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); } } diff --git a/test/Sema/constant-builtins-2.c b/test/Sema/constant-builtins-2.c index 23aa314e0c..68b46bf19a 100644 --- a/test/Sema/constant-builtins-2.c +++ b/test/Sema/constant-builtins-2.c @@ -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]; |