aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Builtins.def19
-rw-r--r--include/clang/AST/Builtins.h8
-rw-r--r--include/clang/AST/Expr.h2
-rw-r--r--lib/AST/Expr.cpp9
-rw-r--r--lib/Sema/SemaDecl.cpp4
-rw-r--r--test/Sema/constant-builtins.c18
6 files changed, 41 insertions, 19 deletions
diff --git a/include/clang/AST/Builtins.def b/include/clang/AST/Builtins.def
index d23cc14eb9..c993a75377 100644
--- a/include/clang/AST/Builtins.def
+++ b/include/clang/AST/Builtins.def
@@ -52,15 +52,16 @@
// n -> nothrow
// c -> const
// F -> this is a libc/libm function with a '__builtin_' prefix added.
+// C -> this builtin can be used as a "constant expression"
// FIXME: gcc has nonnull
// Standard libc/libm functions:
-BUILTIN(__builtin_huge_val, "d", "nc")
-BUILTIN(__builtin_huge_valf, "f", "nc")
-BUILTIN(__builtin_huge_vall, "Ld", "nc")
-BUILTIN(__builtin_inf , "d" , "nc")
-BUILTIN(__builtin_inff , "f" , "nc")
-BUILTIN(__builtin_infl , "Ld" , "nc")
+BUILTIN(__builtin_huge_val, "d", "ncC")
+BUILTIN(__builtin_huge_valf, "f", "ncC")
+BUILTIN(__builtin_huge_vall, "Ld", "ncC")
+BUILTIN(__builtin_inf , "d" , "ncC")
+BUILTIN(__builtin_inff , "f" , "ncC")
+BUILTIN(__builtin_infl , "Ld" , "ncC")
BUILTIN(__builtin_nan, "dcC*" , "ncF")
BUILTIN(__builtin_nanf, "fcC*" , "ncF")
BUILTIN(__builtin_nanl, "LdcC*", "ncF")
@@ -111,9 +112,9 @@ BUILTIN(__builtin_bswap32, "UiUi", "nc")
BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
// Random GCC builtins
-BUILTIN(__builtin_constant_p, "UsUs", "nc")
-BUILTIN(__builtin_classify_type, "i.", "nc")
-BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin_constant_p, "UsUs", "ncC")
+BUILTIN(__builtin_classify_type, "i.", "ncC")
+BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "ncC")
BUILTIN(__builtin_va_start, "va&.", "n")
BUILTIN(__builtin_va_end, "va&", "n")
BUILTIN(__builtin_va_copy, "va&a", "n")
diff --git a/include/clang/AST/Builtins.h b/include/clang/AST/Builtins.h
index 0deaca6a68..10805fa0fa 100644
--- a/include/clang/AST/Builtins.h
+++ b/include/clang/AST/Builtins.h
@@ -73,11 +73,17 @@ public:
}
/// isLibFunction - Return true if this is a builtin for a libc/libm function,
- /// with a "__builtin_" prefix (e.g. __builtin_inf).
+ /// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'F') != 0;
}
+ /// isConstantExpr - Return true if this builtin can be used where a
+ /// constant expression is required.
+ bool isConstantExpr(unsigned ID) const {
+ return strchr(GetRecord(ID).Attributes, 'C') != 0;
+ }
+
/// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
/// as an operand or return type.
bool hasVAListUse(unsigned ID) const {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 16daa64a1c..f7aa351745 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -704,7 +704,7 @@ public:
bool isBuiltinClassifyType(llvm::APSInt &Result) const;
/// isBuiltinConstantExpr - Return true if this built-in call is constant.
- bool isBuiltinConstantExpr() const;
+ bool isBuiltinConstantExpr(ASTContext &Ctx) const;
SourceLocation getRParenLoc() const { return RParenLoc; }
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 6a4b6b0493..14b7b51ebb 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -139,7 +139,7 @@ void CallExpr::setNumArgs(unsigned NumArgs) {
this->NumArgs = NumArgs;
}
-bool CallExpr::isBuiltinConstantExpr() const {
+bool CallExpr::isBuiltinConstantExpr(ASTContext &Ctx) const {
// All simple function calls (e.g. func()) are implicitly cast to pointer to
// function. As a result, we try and obtain the DeclRefExpr from the
// ImplicitCastExpr.
@@ -159,10 +159,7 @@ bool CallExpr::isBuiltinConstantExpr() const {
if (!builtinID)
return false;
- // We have a builtin that is a constant expression
- return builtinID == Builtin::BI__builtin___CFStringMakeConstantString ||
- builtinID == Builtin::BI__builtin_classify_type ||
- builtinID == Builtin::BI__builtin_huge_valf;
+ return Ctx.BuiltinInfo.isConstantExpr(builtinID);
}
bool CallExpr::isBuiltinClassifyType(llvm::APSInt &Result) const {
@@ -585,7 +582,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
return true;
case CallExprClass: {
const CallExpr *CE = cast<CallExpr>(this);
- if (CE->isBuiltinConstantExpr())
+ if (CE->isBuiltinConstantExpr(Ctx))
return true;
if (Loc) *Loc = getLocStart();
return false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9c5c4f2d4b..8214fe4c63 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -878,7 +878,7 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) {
return false;
case Expr::CallExprClass: {
const CallExpr *CE = cast<CallExpr>(Init);
- if (CE->isBuiltinConstantExpr())
+ if (CE->isBuiltinConstantExpr(Context))
return false;
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
@@ -1077,7 +1077,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
return false;
case Expr::CallExprClass: {
const CallExpr *CE = cast<CallExpr>(Init);
- if (CE->isBuiltinConstantExpr())
+ if (CE->isBuiltinConstantExpr(Context))
return false;
Diag(Init->getExprLoc(),
diag::err_init_element_not_constant, Init->getSourceRange());
diff --git a/test/Sema/constant-builtins.c b/test/Sema/constant-builtins.c
new file mode 100644
index 0000000000..875414a109
--- /dev/null
+++ b/test/Sema/constant-builtins.c
@@ -0,0 +1,18 @@
+// RUN: clang -fsyntax-only %s
+
+// Math stuff
+
+float g0 = __builtin_huge_val();
+double g1 = __builtin_huge_valf();
+long double g2 = __builtin_huge_vall();
+float g3 = __builtin_inf();
+double g4 = __builtin_inff();
+long double g5 = __builtin_infl();
+
+// GCC misc stuff
+
+extern int f();
+
+int h0 = __builtin_types_compatible_p(int,float);
+//int h1 = __builtin_choose_expr(1, 10, f());
+//int h2 = __builtin_expect(0, 0);