From: Douglas Gregor Date: Fri, 10 Sep 2010 06:27:15 +0000 (+0000) Subject: Support strlen() and __builtin_strlen() as constant expressions with X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5726d405e71f11feaaf0c8f518abe26e909537a4;p=clang Support strlen() and __builtin_strlen() as constant expressions with the call argument is a string literal. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113580 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(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];