diff mbox series

c++: Avoid strict_aliasing_warning on dependent types or expressions [PR94951]

Message ID 20200505222853.GU8462@tucnak
State New
Headers show
Series c++: Avoid strict_aliasing_warning on dependent types or expressions [PR94951] | expand

Commit Message

Jakub Jelinek May 5, 2020, 10:28 p.m. UTC
Hi!

The following testcase gets a bogus warning during build_base_path,
when cp_build_indirect_ref* calls strict_aliasing_warning with a dependent
expression.  IMHO calling get_alias_set etc. on dependent types feels wrong
to me, we should just defer the warnings in those cases until instantiation
and only handle the cases where neither type nor expr are dependent.

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

2020-05-05  Jakub Jelinek  <jakub@redhat.com>

	PR c++/94951
	* typeck.c (cp_strict_aliasing_warning): New function.
	(cp_build_indirect_ref_1, build_reinterpret_cast_1): Use
	it instead of strict_aliasing_warning.

	* g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C: New test.


	Jakub

Comments

Jason Merrill May 6, 2020, 9:28 p.m. UTC | #1
On 5/5/20 6:28 PM, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase gets a bogus warning during build_base_path,
> when cp_build_indirect_ref* calls strict_aliasing_warning with a dependent
> expression.  IMHO calling get_alias_set etc. on dependent types feels wrong
> to me, we should just defer the warnings in those cases until instantiation
> and only handle the cases where neither type nor expr are dependent.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2020-05-05  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/94951
> 	* typeck.c (cp_strict_aliasing_warning): New function.
> 	(cp_build_indirect_ref_1, build_reinterpret_cast_1): Use
> 	it instead of strict_aliasing_warning.
> 
> 	* g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C: New test.
> 
> --- gcc/cp/typeck.c.jj	2020-03-19 22:54:38.393744684 +0100
> +++ gcc/cp/typeck.c	2020-05-05 18:12:21.964090624 +0200
> @@ -3318,6 +3318,22 @@ build_x_indirect_ref (location_t loc, tr
>       return rval;
>   }
>   
> +/* Like c-family strict_aliasing_warning, but don't warn for dependent
> +   types or expressions.  */
> +
> +static bool
> +cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
> +{
> +  if (processing_template_decl)
> +    {
> +      tree e = expr;
> +      STRIP_NOPS (e);
> +      if (dependent_type_p (type) || type_dependent_expression_p (e))
> +	return false;
> +    }
> +  return strict_aliasing_warning (loc, type, expr);
> +}
> +
>   /* The implementation of the above, and of indirection implied by other
>      constructs.  If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR.  */
>   
> @@ -3360,10 +3376,10 @@ cp_build_indirect_ref_1 (location_t loc,
>   	  /* If a warning is issued, mark it to avoid duplicates from
>   	     the backend.  This only needs to be done at
>   	     warn_strict_aliasing > 2.  */
> -	  if (warn_strict_aliasing > 2)
> -	    if (strict_aliasing_warning (EXPR_LOCATION (ptr),
> -					 type, TREE_OPERAND (ptr, 0)))
> -	      TREE_NO_WARNING (ptr) = 1;
> +	  if (warn_strict_aliasing > 2
> +	      && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
> +					     type, TREE_OPERAND (ptr, 0)))
> +	    TREE_NO_WARNING (ptr) = 1;
>   	}
>   
>         if (VOID_TYPE_P (t))
> @@ -7777,7 +7793,7 @@ build_reinterpret_cast_1 (location_t loc
>         expr = cp_build_addr_expr (expr, complain);
>   
>         if (warn_strict_aliasing > 2)
> -	strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
> +	cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
>   
>         if (expr != error_mark_node)
>   	expr = build_reinterpret_cast_1
> @@ -7891,7 +7907,7 @@ build_reinterpret_cast_1 (location_t loc
>   
>         if (warn_strict_aliasing <= 2)
>   	/* strict_aliasing_warning STRIP_NOPs its expr.  */
> -	strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
> +	cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
>   
>         return build_nop_reinterpret (type, expr);
>       }
> --- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C.jj	2020-05-05 18:18:43.408320000 +0200
> +++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C	2020-05-05 18:17:35.178352212 +0200
> @@ -0,0 +1,12 @@
> +// PR c++/94951
> +// { dg-do compile }
> +// { dg-options "-O2 -Wall" }
> +
> +struct A { int a; };
> +template <int N>
> +struct B : public A
> +{
> +  static B<N> foo () { B<N> t; t.a = 4; return t; }	// { dg-bogus "dereferencing type-punned pointer will break strict-aliasing rules" }
> +};
> +
> +B<0> b = B<0>::foo ();
> 
> 	Jakub
>
diff mbox series

Patch

--- gcc/cp/typeck.c.jj	2020-03-19 22:54:38.393744684 +0100
+++ gcc/cp/typeck.c	2020-05-05 18:12:21.964090624 +0200
@@ -3318,6 +3318,22 @@  build_x_indirect_ref (location_t loc, tr
     return rval;
 }
 
+/* Like c-family strict_aliasing_warning, but don't warn for dependent
+   types or expressions.  */
+
+static bool
+cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
+{
+  if (processing_template_decl)
+    {
+      tree e = expr;
+      STRIP_NOPS (e);
+      if (dependent_type_p (type) || type_dependent_expression_p (e))
+	return false;
+    }
+  return strict_aliasing_warning (loc, type, expr);
+}
+
 /* The implementation of the above, and of indirection implied by other
    constructs.  If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR.  */
 
@@ -3360,10 +3376,10 @@  cp_build_indirect_ref_1 (location_t loc,
 	  /* If a warning is issued, mark it to avoid duplicates from
 	     the backend.  This only needs to be done at
 	     warn_strict_aliasing > 2.  */
-	  if (warn_strict_aliasing > 2)
-	    if (strict_aliasing_warning (EXPR_LOCATION (ptr),
-					 type, TREE_OPERAND (ptr, 0)))
-	      TREE_NO_WARNING (ptr) = 1;
+	  if (warn_strict_aliasing > 2
+	      && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
+					     type, TREE_OPERAND (ptr, 0)))
+	    TREE_NO_WARNING (ptr) = 1;
 	}
 
       if (VOID_TYPE_P (t))
@@ -7777,7 +7793,7 @@  build_reinterpret_cast_1 (location_t loc
       expr = cp_build_addr_expr (expr, complain);
 
       if (warn_strict_aliasing > 2)
-	strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
+	cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
 
       if (expr != error_mark_node)
 	expr = build_reinterpret_cast_1
@@ -7891,7 +7907,7 @@  build_reinterpret_cast_1 (location_t loc
 
       if (warn_strict_aliasing <= 2)
 	/* strict_aliasing_warning STRIP_NOPs its expr.  */
-	strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
+	cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
 
       return build_nop_reinterpret (type, expr);
     }
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C.jj	2020-05-05 18:18:43.408320000 +0200
+++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C	2020-05-05 18:17:35.178352212 +0200
@@ -0,0 +1,12 @@ 
+// PR c++/94951
+// { dg-do compile }
+// { dg-options "-O2 -Wall" }
+
+struct A { int a; };
+template <int N>
+struct B : public A
+{
+  static B<N> foo () { B<N> t; t.a = 4; return t; }	// { dg-bogus "dereferencing type-punned pointer will break strict-aliasing rules" }
+};
+
+B<0> b = B<0>::foo ();