aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--decl.h1
-rw-r--r--expr.c6
-rw-r--r--scope.c19
-rw-r--r--tests/builtin-constant-p.c3
-rw-r--r--tests/builtin-constant-p.qbe2
5 files changed, 22 insertions, 9 deletions
diff --git a/decl.h b/decl.h
index 4abbbac..98fd768 100644
--- a/decl.h
+++ b/decl.h
@@ -14,6 +14,7 @@ enum linkage {
enum builtinkind {
BUILTINALLOCA,
+ BUILTINCONSTANTP,
BUILTININFF,
BUILTINNANF,
BUILTINOFFSETOF,
diff --git a/expr.c b/expr.c
index 4dd16a8..b6e7bbc 100644
--- a/expr.c
+++ b/expr.c
@@ -405,6 +405,8 @@ primaryexpr(struct scope *s)
return e;
}
+static struct expression *condexpr(struct scope *);
+
static struct expression *
builtinfunc(struct scope *s, enum builtinkind kind)
{
@@ -419,6 +421,10 @@ builtinfunc(struct scope *s, enum builtinkind kind)
e->builtin.kind = BUILTINALLOCA;
e->builtin.arg = exprconvert(assignexpr(s), &typeulong);
break;
+ case BUILTINCONSTANTP:
+ /* XXX: does this need to consider address constants? */
+ e = mkconstexpr(&typeint, eval(condexpr(s))->kind == EXPRCONST);
+ break;
case BUILTININFF:
e = mkexpr(EXPRCONST, &typefloat, 0);
/* TODO: use INFINITY here when we can handle musl's math.h */
diff --git a/scope.c b/scope.c
index 1bcd31f..c557f47 100644
--- a/scope.c
+++ b/scope.c
@@ -17,15 +17,16 @@ scopeinit(void)
char *name;
struct declaration decl;
} builtins[] = {
- {"__builtin_alloca", {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}},
- {"__builtin_inff", {.kind = DECLBUILTIN, .builtin = BUILTININFF}},
- {"__builtin_nanf", {.kind = DECLBUILTIN, .builtin = BUILTINNANF}},
- {"__builtin_offsetof", {.kind = DECLBUILTIN, .builtin = BUILTINOFFSETOF}},
- {"__builtin_va_arg", {.kind = DECLBUILTIN, .builtin = BUILTINVAARG}},
- {"__builtin_va_copy", {.kind = DECLBUILTIN, .builtin = BUILTINVACOPY}},
- {"__builtin_va_end", {.kind = DECLBUILTIN, .builtin = BUILTINVAEND}},
- {"__builtin_va_list", {.kind = DECLTYPE, .type = &typevalist}},
- {"__builtin_va_start", {.kind = DECLBUILTIN, .builtin = BUILTINVASTART}},
+ {"__builtin_alloca", {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}},
+ {"__builtin_constant_p", {.kind = DECLBUILTIN, .builtin = BUILTINCONSTANTP}},
+ {"__builtin_inff", {.kind = DECLBUILTIN, .builtin = BUILTININFF}},
+ {"__builtin_nanf", {.kind = DECLBUILTIN, .builtin = BUILTINNANF}},
+ {"__builtin_offsetof", {.kind = DECLBUILTIN, .builtin = BUILTINOFFSETOF}},
+ {"__builtin_va_arg", {.kind = DECLBUILTIN, .builtin = BUILTINVAARG}},
+ {"__builtin_va_copy", {.kind = DECLBUILTIN, .builtin = BUILTINVACOPY}},
+ {"__builtin_va_end", {.kind = DECLBUILTIN, .builtin = BUILTINVAEND}},
+ {"__builtin_va_list", {.kind = DECLTYPE, .type = &typevalist}},
+ {"__builtin_va_start", {.kind = DECLBUILTIN, .builtin = BUILTINVASTART}},
};
struct builtin *b;
diff --git a/tests/builtin-constant-p.c b/tests/builtin-constant-p.c
new file mode 100644
index 0000000..fa16ed3
--- /dev/null
+++ b/tests/builtin-constant-p.c
@@ -0,0 +1,3 @@
+int f(void);
+int x = __builtin_constant_p(1+2*3);
+int y = __builtin_constant_p(f());
diff --git a/tests/builtin-constant-p.qbe b/tests/builtin-constant-p.qbe
new file mode 100644
index 0000000..f92388f
--- /dev/null
+++ b/tests/builtin-constant-p.qbe
@@ -0,0 +1,2 @@
+export data $x = align 4 { w 1, }
+export data $y = align 4 { w 0, }