C++ PATCH for c++/90736 - bogus error with alignof

Message ID 20190610004509.GC5989@redhat.com
State New
Headers show
Series
  • C++ PATCH for c++/90736 - bogus error with alignof
Related show

Commit Message

Marek Polacek June 10, 2019, 12:45 a.m.
The problem here is that we're getting "requested alignment is not an
integer constant" since r261971, because of this part of the patch:

@ -4676,7 +4685,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
         conversion.  */
      return fold (t);

-   if (tcode == UNARY_PLUS_EXPR)
+   /* Handle an array's bounds having been deduced after we built
+      the wrapping expression.  */
+   if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
+     r = op;
+   else if (tcode == UNARY_PLUS_EXPR)
      r = fold_convert (TREE_TYPE (t), op);
    else
      r = fold_build1 (tcode, type, op);

where type was "int" and TREE_TYPE (op) was "const int", so we just used OP
which was an INTEGER_CST of type "const int".  That resulted in a NOP_EXPR
causing the error above.  Previously, we'd fold_build, returning an INTEGER_CST
with type "int".

It seems weird to me to have an INTEGER_CST with a cv-qual type, so the
following patch handles that case in adjust_temp_type.

Bootstrapped/regtested on x86_64-linux, ok for trunk and 9?

2019-06-09  Marek Polacek  <polacek@redhat.com>

	PR c++/90736 - bogus error with alignof.
	* constexpr.c (adjust_temp_type): Use cv_unqualified type.

	* g++.dg/cpp0x/alignof5.C: New test.

Comments

Jason Merrill June 12, 2019, 7:50 p.m. | #1
On 6/9/19 8:45 PM, Marek Polacek wrote:
> The problem here is that we're getting "requested alignment is not an

> integer constant" since r261971, because of this part of the patch:

> 

> @ -4676,7 +4685,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,

>           conversion.  */

>        return fold (t);

> 

> -   if (tcode == UNARY_PLUS_EXPR)

> +   /* Handle an array's bounds having been deduced after we built

> +      the wrapping expression.  */

> +   if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))

> +     r = op;

> +   else if (tcode == UNARY_PLUS_EXPR)

>        r = fold_convert (TREE_TYPE (t), op);

>      else

>        r = fold_build1 (tcode, type, op);

> 

> where type was "int" and TREE_TYPE (op) was "const int", so we just used OP

> which was an INTEGER_CST of type "const int".  That resulted in a NOP_EXPR

> causing the error above.  Previously, we'd fold_build, returning an INTEGER_CST

> with type "int".

> 

> It seems weird to me to have an INTEGER_CST with a cv-qual type, so the

> following patch handles that case in adjust_temp_type.

> 

> Bootstrapped/regtested on x86_64-linux, ok for trunk and 9?


OK.

Jason

Patch

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 10afc419a33..a0d09de064d 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -1337,7 +1337,9 @@  adjust_temp_type (tree type, tree temp)
   if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
     return build0 (EMPTY_CLASS_EXPR, type);
   gcc_assert (scalarish_type_p (type));
-  return cp_fold_convert (type, temp);
+  /* Now we know we're dealing with a scalar, and a prvalue of non-class
+     type is cv-unqualified.  */
+  return cp_fold_convert (cv_unqualified (type), temp);
 }
 
 /* Callback for walk_tree used by unshare_constructor.  */
diff --git gcc/testsuite/g++.dg/cpp0x/alignof5.C gcc/testsuite/g++.dg/cpp0x/alignof5.C
new file mode 100644
index 00000000000..09354d3e1d0
--- /dev/null
+++ gcc/testsuite/g++.dg/cpp0x/alignof5.C
@@ -0,0 +1,6 @@ 
+// PR c++/90736 - bogus error with alignof.
+// { dg-do compile { target c++11 } }
+
+constexpr int fn(const int b) { return b; }
+constexpr int c = fn(alignof(int));
+alignas(c) char d;