diff options
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/constexpr-strlen.cpp | 15 |
2 files changed, 23 insertions, 1 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 1ad0bc5474b..fc3c5aac01c 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -3891,8 +3891,15 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { case Builtin::BI__builtin_expect: return Visit(E->getArg(0)); - + case Builtin::BIstrlen: + // A call to strlen is not a constant expression. + if (Info.getLangOpts().CPlusPlus0x) + Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_function) + << /*isConstexpr*/0 << /*isConstructor*/0 << "'strlen'"; + else + Info.CCEDiag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); + // Fall through. case Builtin::BI__builtin_strlen: // As an extension, we support strlen() and __builtin_strlen() as constant // expressions when the argument is a string literal. diff --git a/clang/test/SemaCXX/constexpr-strlen.cpp b/clang/test/SemaCXX/constexpr-strlen.cpp new file mode 100644 index 00000000000..5e28e7f0ce5 --- /dev/null +++ b/clang/test/SemaCXX/constexpr-strlen.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify -pedantic + +# 1 "/usr/include/string.h" 1 3 4 +extern "C" { + typedef decltype(sizeof(int)) size_t; + extern size_t strlen(const char *p); +} + +# 10 "SemaCXX/constexpr-strlen.cpp" 2 +constexpr int n = __builtin_strlen("hello"); // ok +constexpr int m = strlen("hello"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strlen' cannot be used in a constant expression}} + +// Make sure we can evaluate a call to strlen. +int arr[3]; // expected-note {{here}} +int k = arr[strlen("hello")]; // expected-warning {{array index 5}} |