A __builtin_constant_p() returns 0 with a function type.

llvm-svn: 347480
This commit is contained in:
Bill Wendling 2018-11-22 22:58:06 +00:00
parent b239763384
commit 46acc72cf4
2 changed files with 27 additions and 1 deletions

View File

@ -1935,7 +1935,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const Expr *Arg = E->getArg(0); const Expr *Arg = E->getArg(0);
QualType ArgType = Arg->getType(); QualType ArgType = Arg->getType();
if (!hasScalarEvaluationKind(ArgType)) if (!hasScalarEvaluationKind(ArgType) || ArgType->isFunctionType())
// We can only reason about scalar types. // We can only reason about scalar types.
return RValue::get(ConstantInt::get(ResultType, 0)); return RValue::get(ConstantInt::get(ResultType, 0));

View File

@ -128,3 +128,29 @@ int test13() {
// CHECK: ret i32 1 // CHECK: ret i32 1
return __builtin_constant_p(&test10 != 0); return __builtin_constant_p(&test10 != 0);
} }
typedef unsigned long uintptr_t;
#define assign(p, v) ({ \
uintptr_t _r_a_p__v = (uintptr_t)(v); \
if (__builtin_constant_p(v) && _r_a_p__v == (uintptr_t)0) { \
union { \
uintptr_t __val; \
char __c[1]; \
} __u = { \
.__val = (uintptr_t)_r_a_p__v \
}; \
*(volatile unsigned int*)&p = *(unsigned int*)(__u.__c); \
__u.__val; \
} \
_r_a_p__v; \
})
typedef void fn_p(void);
extern fn_p *dest_p;
static void src_fn(void) {
}
void test14() {
assign(dest_p, src_fn);
}