Commit 109d2197 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/50060 (intrinsics not folded by the middle-end)

	PR c++/50060
	* constexpr.c (cxx_eval_builtin_function_call): Pass false as lval
	when evaluating call arguments.  Use fold_builtin_call_array instead
	of fold_build_call_array_loc, return t if it returns NULL.  Otherwise
	check the result with potential_constant_expression and call
	cxx_eval_constant_expression on it.

	* g++.dg/cpp0x/constexpr-50060.C: New test.
	* g++.dg/cpp1y/constexpr-50060.C: New test.

From-SVN: r238520
parent 2d06ca74
2016-07-20 Jakub Jelinek <jakub@redhat.com>
PR c++/50060
* constexpr.c (cxx_eval_builtin_function_call): Pass false as lval
when evaluating call arguments. Use fold_builtin_call_array instead
of fold_build_call_array_loc, return t if it returns NULL. Otherwise
check the result with potential_constant_expression and call
cxx_eval_constant_expression on it.
2016-07-19 Jason Merrill <jason@redhat.com> 2016-07-19 Jason Merrill <jason@redhat.com>
PR c++/67164 PR c++/67164
......
...@@ -1105,7 +1105,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, ...@@ -1105,7 +1105,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
for (i = 0; i < nargs; ++i) for (i = 0; i < nargs; ++i)
{ {
args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i), args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i),
lval, &dummy1, &dummy2); false, &dummy1, &dummy2);
if (bi_const_p) if (bi_const_p)
/* For __built_in_constant_p, fold all expressions with constant values /* For __built_in_constant_p, fold all expressions with constant values
even if they aren't C++ constant-expressions. */ even if they aren't C++ constant-expressions. */
...@@ -1114,13 +1114,31 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, ...@@ -1114,13 +1114,31 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
bool save_ffbcp = force_folding_builtin_constant_p; bool save_ffbcp = force_folding_builtin_constant_p;
force_folding_builtin_constant_p = true; force_folding_builtin_constant_p = true;
new_call = fold_build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t), new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
CALL_EXPR_FN (t), nargs, args); CALL_EXPR_FN (t), nargs, args);
/* Fold away the NOP_EXPR from fold_builtin_n. */
new_call = fold (new_call);
force_folding_builtin_constant_p = save_ffbcp; force_folding_builtin_constant_p = save_ffbcp;
VERIFY_CONSTANT (new_call); if (new_call == NULL)
return new_call; {
if (!*non_constant_p && !ctx->quiet)
{
new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
CALL_EXPR_FN (t), nargs, args);
error ("%q+E is not a constant expression", new_call);
}
*non_constant_p = true;
return t;
}
if (!potential_constant_expression (new_call))
{
if (!*non_constant_p && !ctx->quiet)
error ("%q+E is not a constant expression", new_call);
*non_constant_p = true;
return t;
}
return cxx_eval_constant_expression (&new_ctx, new_call, lval,
non_constant_p, overflow_p);
} }
/* TEMP is the constant value of a temporary object of type TYPE. Adjust /* TEMP is the constant value of a temporary object of type TYPE. Adjust
......
2016-07-20 Jakub Jelinek <jakub@redhat.com>
PR c++/50060
* g++.dg/cpp0x/constexpr-50060.C: New test.
* g++.dg/cpp1y/constexpr-50060.C: New test.
2016-07-20 Martin Liska <mliska@suse.cz> 2016-07-20 Martin Liska <mliska@suse.cz>
* gfortran.dg/graphite/pr71898.f90: New test. * gfortran.dg/graphite/pr71898.f90: New test.
......
// PR c++/50060
// { dg-do compile { target c++11 } }
extern "C" double frexp (double, int *);
struct S
{
constexpr S (double a) : y {}, x (frexp (a, &y)) {} // { dg-error "is not a constant expression" "S" { target { ! c++14 } } }
double x;
int y;
};
struct T
{
constexpr T (double a) : y {}, x ((y = 1, 0.8125)) {} // { dg-error "is not a constant-expression" "T" { target { ! c++14 } } }
double x;
int y;
};
static_assert (S (6.5).x == 0.8125, ""); // { dg-error "non-constant condition for static assertion|in constexpr expansion" "" { target { ! c++14 } } }
static_assert (T (6.5).x == 0.8125, ""); // { dg-error "non-constant condition for static assertion|called in a constant expression" "" { target { ! c++14 } } }
// PR c++/50060
// { dg-do compile { target c++14 } }
// sincos and lgamma_r aren't available in -std=c++14,
// only in -std=gnu++14. Use __builtin_* in that case.
extern "C" void sincos (double, double *, double *);
extern "C" double frexp (double, int *);
extern "C" double modf (double, double *);
extern "C" double remquo (double, double, int *);
extern "C" double lgamma_r (double, int *);
constexpr double
f0 (double x)
{
double y {};
double z {};
__builtin_sincos (x, &y, &z);
return y;
}
constexpr double
f1 (double x)
{
double y {};
double z {};
__builtin_sincos (x, &y, &z);
return z;
}
constexpr double
f2 (double x)
{
int y {};
return frexp (x, &y);
}
constexpr int
f3 (double x)
{
int y {};
frexp (x, &y);
return y;
}
constexpr double
f4 (double x)
{
double y {};
return modf (x, &y);
}
constexpr double
f5 (double x)
{
double y {};
modf (x, &y);
return y;
}
constexpr double
f6 (double x, double y)
{
int z {};
return remquo (x, y, &z);
}
constexpr int
f7 (double x, double y)
{
int z {};
remquo (x, y, &z);
return z;
}
constexpr double
f8 (double x)
{
int y {};
return __builtin_lgamma_r (x, &y);
}
constexpr int
f9 (double x)
{
int y {};
__builtin_lgamma_r (x, &y);
return y;
}
static_assert (f0 (0.0) == 0.0, "");
static_assert (f1 (0.0) == 1.0, "");
static_assert (f2 (6.5) == 0.8125, "");
static_assert (f3 (6.5) == 3, "");
static_assert (f4 (-7.25) == -0.25, "");
static_assert (f5 (-7.25) == -7.0, "");
static_assert (f6 (3.0, 2.0) == -1.0, "");
static_assert (f7 (3.0, 2.0) == 2, "");
static_assert (f8 (0.75) >= 0.20 && f8 (0.75) <= 0.21, "");
static_assert (f8 (0.75) >= 0.20 && f8 (0.75) <= 0.21, "");
static_assert (f9 (0.75) == 1, "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment