diff mbox

c++/78774 - [6/7 Regression] ICE in constexpr string literals and templates

Message ID 9cdcd33a-b903-5534-0130-0e0d44b2bf7b@gmail.com
State New
Headers show

Commit Message

Martin Sebor Dec. 12, 2016, 4:51 p.m. UTC
The attached patch removes the unsafe assumption behind the ICE.
Is this okay for both trunk and GCC 6?

Thanks
Martin

Comments

Jason Merrill Dec. 13, 2016, 3:53 a.m. UTC | #1
On 12/12/2016 11:51 AM, Martin Sebor wrote:
> The attached patch removes the unsafe assumption behind the ICE.

> Is this okay for both trunk and GCC 6?


> +	      && TREE_CODE (innertype) == REFERENCE_TYPE

> +              && TREE_CODE (TREE_TYPE (innertype)) == FUNCTION_TYPE

> +              && TREE_CODE (innertype) == REFERENCE_TYPE


Let's also remove this redundant REFERENCE_TYPE check.  OK with that change.

Jason
Martin Sebor Dec. 15, 2016, 3:10 a.m. UTC | #2
Jakub,

Do you approve backporting this fix to the 6.x branch?

Martin

On 12/12/2016 08:53 PM, Jason Merrill wrote:
> On 12/12/2016 11:51 AM, Martin Sebor wrote:

>> The attached patch removes the unsafe assumption behind the ICE.

>> Is this okay for both trunk and GCC 6?

>

>> +          && TREE_CODE (innertype) == REFERENCE_TYPE

>> +              && TREE_CODE (TREE_TYPE (innertype)) == FUNCTION_TYPE

>> +              && TREE_CODE (innertype) == REFERENCE_TYPE

>

> Let's also remove this redundant REFERENCE_TYPE check.  OK with that

> change.

>

> Jason

>

>
Jakub Jelinek Dec. 15, 2016, 7:50 a.m. UTC | #3
On Wed, Dec 14, 2016 at 08:10:10PM -0700, Martin Sebor wrote:
> Do you approve backporting this fix to the 6.x branch?


Yes, but please wait a little bit with that (i.e. only commit it after
6.3 is released next week).

I'm also surprised this code does not care about what TREE_CODE inner is,
handles all kinds of trees that have at least one operand.  Generally,
operands of different trees may mean different things.

You could have also fixed the formatting bugs right next to it:
              && 0 < TREE_OPERAND_LENGTH (inner)

This should be && TREE_OPERAND_LENGTH (inner) > 0

              && reject_gcc_builtin (TREE_OPERAND (inner, 0)))
              return error_mark_node;

and this line should be indented 2 positions after the above if,
i.e. 2 positions before &&.  Plus the whole block uses spaces instead of tabs.

	Jakub
diff mbox

Patch

PR c++/78774 - [6/7 Regression] ICE in constexpr string literals and templates

gcc/cp/ChangeLog:

	PR c++/78774
	* pt.c (convert_template_argument): Avoid assuming operand type
	is non-null since that of SCOPE_REF is not.

gcc/testsuite/ChangeLog:

	PR c++/78774
	* g++.dg/cpp1y/pr78774.C: New test.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 97d0b48..1d68fcc 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7375,9 +7375,11 @@  convert_template_argument (tree parm,
           /* Reject template arguments that are references to built-in
              functions with no library fallbacks.  */
           const_tree inner = TREE_OPERAND (val, 0);
-          if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE
-              && TREE_CODE (TREE_TYPE (TREE_TYPE (inner))) == FUNCTION_TYPE
-              && TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE
+	  const_tree innertype = TREE_TYPE (inner);
+          if (innertype
+	      && TREE_CODE (innertype) == REFERENCE_TYPE
+              && TREE_CODE (TREE_TYPE (innertype)) == FUNCTION_TYPE
+              && TREE_CODE (innertype) == REFERENCE_TYPE
               && 0 < TREE_OPERAND_LENGTH (inner)
               && reject_gcc_builtin (TREE_OPERAND (inner, 0)))
               return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr78774.C b/gcc/testsuite/g++.dg/cpp1y/pr78774.C
new file mode 100644
index 0000000..c77032d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr78774.C
@@ -0,0 +1,9 @@ 
+// PR c++/78774 - [6/7 Regression] ICE in constexpr string literals and
+// templates
+// { dg-do compile { target c++14 } }
+
+template <int> struct ops {
+  template <int> struct A;
+  template <int *Ptr> using explode = typename A<*Ptr>::join;
+};
+template <typename Ts> typename ops<'\0'>::explode<Ts::join>::type a;