This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH] [PR/13243] Detect more non constant expressions (regression in mainline)


Jason Merrill <jason@redhat.com> wrote:

> No.  There are address constant-expressions, too, as described in 5.19p4.

Ok, but that kind of contant-expressions are valid only for non-local static
object initialization, for which we don't set constant_expression_p as far as I
can tell. I should have specified this in the mail, sorry.

Another thing that might not be crystal clear which I forgot about is that this
patch doesn't affect other entries in the 14.3.2/1 list (like pointer to
members or addresses to an object/function with external linkage, or even a
single non-type template parameter of non-integral/enumaration type -as checked
by dep5 in my testcase-) because those conditions are directly checked within
cp_parser_template_argument, before trying to parse the more generic constant
expression.

> and so your new test is appropriate.  The name should be fixed accordingly,
> as should the error message in your patch and the comment in your testcase.

The generic error message emitted by "cp_parser_non_constant_expression" uses
the term "constant-expression". Anyway, I changed my error message.

> Also, we don't capitalize the first letter in an error message.

Done. I didn't retest the patch because it's only ChangLog, comment, and
literal changes. OK for mainline?

Giovanni Bajo




2003-12-07  Giovanni Bajo  <giovannibajo@gcc.gnu.org>

        PR c++/13243
        * parser.c (cp_parser_unary_expression): Emit an error when
        INDIRECT_REF and ADDR_EXPR are used in an integral
        constant-expression.
        * pt.c (value_dependent_expression_p): Handle recursively
        INDIRECT_REF and ARRAY_REF trees.
        * semantics.c (finish_id_expression): Refactor the code to handle
        template parameters, and emit a more informative error message
        when they are used within non integral constant expressions.


2003-12-07  Giovanni Bajo  <giovannibajo@gcc.gnu.org>

        PR c++/13243
        * g++.dg/template/dependent-expr3.C: Adjust to test for the new error.
        * g++.dg/template/nontype3.C: New test.


Index: parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 parser.c
*** parser.c    6 Dec 2003 06:53:01 -0000       1.129
--- parser.c    7 Dec 2003 23:25:40 -0000
*************** cp_parser_unary_expression (cp_parser *p
*** 4196,4204 ****
--- 4196,4217 ----
        switch (unary_operator)
        {
        case INDIRECT_REF:
+         if (parser->constant_expression_p)
+         {
+           if (!parser->allow_non_constant_expression_p)
+             return cp_parser_non_constant_expression ("unary `*'");
+           parser->non_constant_expression_p = true;
+         }
          return build_x_indirect_ref (cast_expression, "unary *");

        case ADDR_EXPR:
+         if (parser->constant_expression_p)
+         {
+           if (!parser->allow_non_constant_expression_p)
+             return cp_parser_non_constant_expression ("unary `&'");
+           parser->non_constant_expression_p = true;
+         }
+         /* Fall through.  */
        case BIT_NOT_EXPR:
          return build_x_unary_op (unary_operator, cast_expression);

Index: pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.799
diff -c -3 -p -r1.799 pt.c
*** pt.c        2 Dec 2003 15:46:51 -0000       1.799
--- pt.c        7 Dec 2003 23:25:46 -0000
*************** value_dependent_expression_p (tree expre
*** 11717,11722 ****
--- 11717,11727 ----
    if (TREE_CODE (expression) == COMPONENT_REF)
      return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
            || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
+   if (TREE_CODE (expression) == ARRAY_REF)
+     return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
+           || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
+   if (TREE_CODE (expression) == INDIRECT_REF)
+     return (value_dependent_expression_p (TREE_OPERAND (expression, 0)));
    /* A constant expression is value-dependent if any subexpression is
       value-dependent.  */
    if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
Index: semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.374
diff -c -3 -p -r1.374 semantics.c
*** semantics.c 4 Dec 2003 05:02:18 -0000       1.374
--- semantics.c 7 Dec 2003 23:25:48 -0000
*************** finish_id_expression (tree id_expression
*** 2392,2405 ****
      }

    /* If the name resolved to a template parameter, there is no
!      need to look it up again later.  Similarly, we resolve
!      enumeration constants to their underlying values.  */
!   if (TREE_CODE (decl) == CONST_DECL)
      {
        *idk = CP_ID_KIND_NONE;
!       if (DECL_TEMPLATE_PARM_P (decl) || !processing_template_decl)
        return DECL_INITIAL (decl);
!       return decl;
      }
    else
      {
--- 2392,2423 ----
      }

    /* If the name resolved to a template parameter, there is no
!      need to look it up again later.  */
!   if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
!       || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
      {
        *idk = CP_ID_KIND_NONE;
!       if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
!       decl = TEMPLATE_PARM_DECL (decl);
!       if (constant_expression_p
!       && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
!       {
!       if (!allow_non_constant_expression_p)
!         error ("template parameter `%D' of type `%T' is not allowed in "
!         "an integral constant expression because it is not of integral "
!         "or enumeration type", decl, TREE_TYPE (decl));
!       *non_constant_expression_p = true;
!       }
!       return DECL_INITIAL (decl);
!     }
!   /* Similarly, we resolve enumeration constants to their
!      underlying values.  */
!   else if (TREE_CODE (decl) == CONST_DECL)
!     {
!       *idk = CP_ID_KIND_NONE;
!       if (!processing_template_decl)
        return DECL_INITIAL (decl);
!       return decl;
      }
    else
      {
*************** finish_id_expression (tree id_expression
*** 2516,2536 ****
        }

        /* Only certain kinds of names are allowed in constant
!        expression.  Enumerators have already been handled above.  */
        if (constant_expression_p)
        {
-         /* Non-type template parameters of integral or enumeration
-            type are OK.  */
-         if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX
-             && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
-         ;
          /* Const variables or static data members of integral or
             enumeration types initialized with constant expressions
             are OK.  */
!         else if (TREE_CODE (decl) == VAR_DECL
!                  && CP_TYPE_CONST_P (TREE_TYPE (decl))
!                  && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
!                  && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
            ;
          else
            {
--- 2534,2550 ----
        }

        /* Only certain kinds of names are allowed in constant
!        expression.  Enumerators and template parameters
!        have already been handled above.  */
        if (constant_expression_p)
        {
          /* Const variables or static data members of integral or
             enumeration types initialized with constant expressions
             are OK.  */
!         if (TREE_CODE (decl) == VAR_DECL
!             && CP_TYPE_CONST_P (TREE_TYPE (decl))
!             && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
!             && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
            ;
          else
            {
Index: g++.dg/template/dependent-expr3.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/dependent-expr3.C,v
retrieving revision 1.1
diff -c -p -r1.1 dependent-expr3.C
*** g++.dg/template/dependent-expr3.C   2 Dec 2003 12:10:32 -0000       1.1
--- g++.dg/template/dependent-expr3.C   8 Dec 2003 02:55:33 -0000
*************** template <typename K> struct Y : K {
*** 9,14 ****
  };

  template <class T> struct Z {
!   S< (bool)(&static_cast<Y<T> *>(0)->x == 0) >
!     s;
  };
--- 9,13 ----
  };

  template <class T> struct Z {
!   S< (bool)(&static_cast<Y<T> *>(0)->x == 0) > s; // { dg-error "" "" }
  };


// { dg-do compile }
// Origin: <drow at gcc dot gnu dot org>,
//         <giovannibajo at gcc dot gnu dot org>
// c++/13243: Template parameters of non integral or enumeration type can't be
//  used for integral constant expressions. ADDR_EXPR and INDIRECT_REF are
//  invalid too.

template <int T> class foo {};
template <int *T> class bar {};

template <int *PI>
void dep5(bar<PI> *);

template <int *PI>
void dep6(bar<PI+1> *); // { dg-error "" "integral or enumeration" }

template <int I>
void dep7(bar<I+1> *);

template <int *PI>
void dep8(foo< *PI > *); // { dg-error "" "integral or enumeration" }

template <int PI[1]>
void dep9(foo< *PI > *); // { dg-error "" "integral or enumeration" }

template <int PI[1]>
void dep9a(foo< sizeof(*PI) > *);

template <int PI[1]>
void dep10(foo< PI[0] > *); // { dg-error "" "integral or enumeration" }

template <int I>
void dep11(foo< *&I > *); // { dg-error "" "constant-expression" }

template <int I>
void dep12(foo< (&I)[4] > *); // { dg-error "" "constant-expression" }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]