From 46acc72cf41b475db1f7a534202f69476244b90d Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 22 Nov 2018 22:58:06 +0000 Subject: [PATCH] A __builtin_constant_p() returns 0 with a function type. llvm-svn: 347480 --- clang/lib/CodeGen/CGBuiltin.cpp | 2 +- clang/test/CodeGen/builtin-constant-p.c | 26 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9301bfb0e90b..b1323031d9a1 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1935,7 +1935,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, const Expr *Arg = E->getArg(0); QualType ArgType = Arg->getType(); - if (!hasScalarEvaluationKind(ArgType)) + if (!hasScalarEvaluationKind(ArgType) || ArgType->isFunctionType()) // We can only reason about scalar types. return RValue::get(ConstantInt::get(ResultType, 0)); diff --git a/clang/test/CodeGen/builtin-constant-p.c b/clang/test/CodeGen/builtin-constant-p.c index 978ec4c8f549..3f1225fb8b29 100644 --- a/clang/test/CodeGen/builtin-constant-p.c +++ b/clang/test/CodeGen/builtin-constant-p.c @@ -128,3 +128,29 @@ int test13() { // CHECK: ret i32 1 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); +}