From patchwork Wed Feb 22 22:37:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 731333 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vTC163WmHz9s4s for ; Thu, 23 Feb 2017 09:37:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="uZR27/o5"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=EE2ScqWKw0ZUH2HUx nYRJdOfvq8gv4XhuvCJwfz3d7Fj5q5wACRTIi55ZTug6hyZn+u03NX8+SUXjw1PB 4ttdog8ePJqjRhxSWRG2s0c2Jh8eubyjXBVJ6JdOQCJFPGH7jqjtR1Jsqgm9ZBNE fSTl/h1LhqMfNtnV2gKyOZna/o= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:in-reply-to; s=default; bh=qtg7q+DFvFXaNb8nZjI8pJN 9E6s=; b=uZR27/o5G2DSSg+jzYx9AV2Pc601UixoQ8g8BOp8odhG7ItRt39KPRd L4SP0gELaPTacSG0EaqBsyJ5hToStJoegbMXhx1S9DfHY0denRG34hpZi7XJ3i2q tXrInlfZ5QvVjvuUbXmvgem/JiEhIvr8aCFhT41TaldSzkE6T9bY= Received: (qmail 98500 invoked by alias); 22 Feb 2017 22:37:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 98486 invoked by uid 89); 22 Feb 2017 22:37:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 22 Feb 2017 22:37:17 +0000 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E14B63A769D for ; Wed, 22 Feb 2017 22:37:17 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-117-76.ams2.redhat.com [10.36.117.76]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5A1B3B1223; Wed, 22 Feb 2017 22:37:17 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id v1MMbDrl024784; Wed, 22 Feb 2017 23:37:13 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v1MMb7jp024783; Wed, 22 Feb 2017 23:37:07 +0100 Date: Wed, 22 Feb 2017 23:37:07 +0100 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches List Subject: Re: [C++ PATCH] Fix ICE with OpenMP/OpenACC/Cilk+ constructs in constexpr functions (PR c++/79664) Message-ID: <20170222223707.GD1849@tucnak> Reply-To: Jakub Jelinek References: <20170222215031.GB1849@tucnak> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.7.1 (2016-10-04) X-IsSubscribed: yes On Wed, Feb 22, 2017 at 01:58:28PM -0800, Jason Merrill wrote: > On Wed, Feb 22, 2017 at 1:50 PM, Jakub Jelinek wrote: > > This patch does a few things: > > 2) all but one error in potential_constant_expression_1 to error_at with > > location_of (t) > > I'd prefer to calculate the location once at the top of the function > rather than at every call to error_at. Given that, I think > EXPR_LOC_OR_LOC is better than location_of, as the latter will give > the wrong result for a decl. OK with that change. Ok, here is what I've committed then: 2017-02-22 Jakub Jelinek PR c++/79664 * parser.c (cp_parser_omp_teams, cp_parser_omp_target): Use SET_EXPR_LOCATION on OMP_TARGET/OMP_TEAMS tree. * constexpr.c (potential_constant_expression_1): Handle OMP_*, OACC_* and CILK_* trees. Use error_at with EXPR_LOC_OR_LOC (t, input_location) computed early instead of error, or error_at with location_of (t). * g++.dg/gomp/teams-1.C: Adjust expected diagnostic location. * g++.dg/cpp1y/constexpr-throw.C: Likewise. * g++.dg/gomp/pr79664.C: New test. Jakub --- gcc/cp/parser.c.jj 2017-02-22 22:32:36.659695471 +0100 +++ gcc/cp/parser.c 2017-02-22 23:00:21.472093702 +0100 @@ -35526,6 +35526,7 @@ cp_parser_omp_teams (cp_parser *parser, OMP_TEAMS_CLAUSES (ret) = clauses; OMP_TEAMS_BODY (ret) = body; OMP_TEAMS_COMBINED (ret) = 1; + SET_EXPR_LOCATION (ret, loc); return add_stmt (ret); } } @@ -35547,6 +35548,7 @@ cp_parser_omp_teams (cp_parser *parser, TREE_TYPE (stmt) = void_type_node; OMP_TEAMS_CLAUSES (stmt) = clauses; OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p); + SET_EXPR_LOCATION (stmt, loc); return add_stmt (stmt); } @@ -35965,6 +35967,7 @@ cp_parser_omp_target (cp_parser *parser, OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; OMP_TARGET_BODY (stmt) = body; OMP_TARGET_COMBINED (stmt) = 1; + SET_EXPR_LOCATION (stmt, pragma_tok->location); add_stmt (stmt); pc = &OMP_TARGET_CLAUSES (stmt); goto check_clauses; --- gcc/cp/constexpr.c.jj 2017-02-22 22:32:34.490723479 +0100 +++ gcc/cp/constexpr.c 2017-02-22 23:03:12.472864242 +0100 @@ -5001,10 +5001,11 @@ potential_constant_expression_1 (tree t, return false; if (t == NULL_TREE) return true; + location_t loc = EXPR_LOC_OR_LOC (t, input_location); if (TREE_THIS_VOLATILE (t) && !DECL_P (t)) { if (flags & tf_error) - error ("expression %qE has side-effects", t); + error_at (loc, "expression %qE has side-effects", t); return false; } if (CONSTANT_CLASS_P (t)) @@ -5086,8 +5087,7 @@ potential_constant_expression_1 (tree t, { /* fold_call_expr can't do anything with IFN calls. */ if (flags & tf_error) - error_at (EXPR_LOC_OR_LOC (t, input_location), - "call to internal function %qE", t); + error_at (loc, "call to internal function %qE", t); return false; } } @@ -5105,8 +5105,8 @@ potential_constant_expression_1 (tree t, { if (flags & tf_error) { - error_at (EXPR_LOC_OR_LOC (t, input_location), - "call to non-constexpr function %qD", fun); + error_at (loc, "call to non-constexpr function %qD", + fun); explain_invalid_constexpr_fn (fun); } return false; @@ -5199,8 +5199,7 @@ potential_constant_expression_1 (tree t, && !integer_zerop (from)) { if (flags & tf_error) - error_at (EXPR_LOC_OR_LOC (t, input_location), - "reinterpret_cast from integer to pointer"); + error_at (loc, "reinterpret_cast from integer to pointer"); return false; } return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR)); @@ -5266,7 +5265,7 @@ potential_constant_expression_1 (tree t, && !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (x))) { if (flags & tf_error) - error ("use of % in a constant expression"); + error_at (loc, "use of % in a constant expression"); return false; } return true; @@ -5354,10 +5353,40 @@ potential_constant_expression_1 (tree t, case DELETE_EXPR: case VEC_DELETE_EXPR: case THROW_EXPR: + case OMP_PARALLEL: + case OMP_TASK: + case OMP_FOR: + case OMP_DISTRIBUTE: + case OMP_TASKLOOP: + case OMP_TEAMS: + case OMP_TARGET_DATA: + case OMP_TARGET: + case OMP_SECTIONS: + case OMP_ORDERED: + case OMP_CRITICAL: + case OMP_SINGLE: + case OMP_SECTION: + case OMP_MASTER: + case OMP_TASKGROUP: + case OMP_TARGET_UPDATE: + case OMP_TARGET_ENTER_DATA: + case OMP_TARGET_EXIT_DATA: case OMP_ATOMIC: case OMP_ATOMIC_READ: case OMP_ATOMIC_CAPTURE_OLD: case OMP_ATOMIC_CAPTURE_NEW: + case OACC_PARALLEL: + case OACC_KERNELS: + case OACC_DATA: + case OACC_HOST_DATA: + case OACC_LOOP: + case OACC_CACHE: + case OACC_DECLARE: + case OACC_ENTER_DATA: + case OACC_EXIT_DATA: + case OACC_UPDATE: + case CILK_SIMD: + case CILK_FOR: /* GCC internal stuff. */ case VA_ARG_EXPR: case OBJ_TYPE_REF: @@ -5366,7 +5395,7 @@ potential_constant_expression_1 (tree t, case AT_ENCODE_EXPR: fail: if (flags & tf_error) - error ("expression %qE is not a constant expression", t); + error_at (loc, "expression %qE is not a constant expression", t); return false; case TYPEID_EXPR: @@ -5378,8 +5407,8 @@ potential_constant_expression_1 (tree t, && TYPE_POLYMORPHIC_P (TREE_TYPE (e))) { if (flags & tf_error) - error ("typeid-expression is not a constant expression " - "because %qE is of polymorphic type", e); + error_at (loc, "typeid-expression is not a constant expression " + "because %qE is of polymorphic type", e); return false; } return true; @@ -5438,8 +5467,9 @@ potential_constant_expression_1 (tree t, constant expression. */ { if (flags & tf_error) - error ("cast to non-integral type %qT in a constant expression", - TREE_TYPE (t)); + error_at (loc, + "cast to non-integral type %qT in a constant expression", + TREE_TYPE (t)); return false; } @@ -5504,8 +5534,8 @@ potential_constant_expression_1 (tree t, { if (flags & tf_error) { - error ("temporary of non-literal type %qT in a " - "constant expression", TREE_TYPE (t)); + error_at (loc, "temporary of non-literal type %qT in a " + "constant expression", TREE_TYPE (t)); explain_non_literal_class (TREE_TYPE (t)); } return false; @@ -5657,8 +5687,7 @@ potential_constant_expression_1 (tree t, if (COND_EXPR_IS_VEC_DELETE (t)) { if (flags & tf_error) - error_at (location_of (t), - "% is not a constant expression"); + error_at (loc, "% is not a constant expression"); return false; } /* Fall through. */ @@ -5681,7 +5710,7 @@ potential_constant_expression_1 (tree t, want_rval, strict, tf_none)) return true; if (flags & tf_error) - error ("expression %qE is not a constant expression", t); + error_at (loc, "expression %qE is not a constant expression", t); return false; case VEC_INIT_EXPR: @@ -5689,7 +5718,7 @@ potential_constant_expression_1 (tree t, return true; if (flags & tf_error) { - error ("non-constant array initialization"); + error_at (loc, "non-constant array initialization"); diagnose_non_constexpr_vec_init (t); } return false; @@ -5710,7 +5739,7 @@ potential_constant_expression_1 (tree t, if (breaks (target) || continues (target)) return true; if (flags & tf_error) - error ("% is not a constant expression"); + error_at (loc, "% is not a constant expression"); return false; } --- gcc/testsuite/g++.dg/gomp/teams-1.C.jj 2017-02-22 22:32:34.279726204 +0100 +++ gcc/testsuite/g++.dg/gomp/teams-1.C 2017-02-22 23:00:21.474093676 +0100 @@ -26,7 +26,7 @@ foo (int x) { #pragma omp target teams { case 0:; } // { dg-error "jump" } - // { dg-warning "statement will never be executed" "" { target *-*-* } 28 } + // { dg-warning "statement will never be executed" "" { target *-*-* } 27 } // { dg-message "enters" "" { target *-*-* } 28 } } } --- gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C.jj 2017-02-22 22:32:34.236726759 +0100 +++ gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C 2017-02-22 23:00:21.474093676 +0100 @@ -7,19 +7,19 @@ constexpr void f1() { constexpr void f2() { if (true) - throw; -} // { dg-error "not a constant expression" } + throw; // { dg-error "not a constant expression" } +} constexpr void f3() { if (false) ; else - throw; -}// { dg-error "not a constant expression" } + throw; // { dg-error "not a constant expression" } +} constexpr void f4() { - throw; -}// { dg-error "not a constant expression" } + throw; // { dg-error "not a constant expression" } +} constexpr int fun(int n) { switch (n) { --- gcc/testsuite/g++.dg/gomp/pr79664.C.jj 2017-02-22 23:00:21.475093662 +0100 +++ gcc/testsuite/g++.dg/gomp/pr79664.C 2017-02-22 23:00:21.475093662 +0100 @@ -0,0 +1,168 @@ +// PR c++/79664 +// { dg-do compile } +// { dg-options "-std=c++14 -fopenmp" } + +constexpr int +f1 () +{ + int i = 0; +#pragma omp parallel for // { dg-error "is not a constant expression" } + for (i = 0; i < 10; ++i) + ; + return 0; +} + +constexpr int +f2 () +{ + int i = 0; +#pragma omp parallel // { dg-error "is not a constant expression" } + i = 5; + return 0; +} + +constexpr int +f3 () +{ + int i = 0; +#pragma omp task // { dg-error "is not a constant expression" } + i = 5; + return 0; +} + +constexpr int +f4 () +{ + int i = 0; +#pragma omp for // { dg-error "is not a constant expression" } + for (i = 0; i < 10; ++i) + ; + return 0; +} + +constexpr int +f5 () +{ + int i = 0; +#pragma omp taskloop // { dg-error "is not a constant expression" } + for (i = 0; i < 10; ++i) + ; + return 0; +} + +constexpr int +f6 () +{ + int i = 0; +#pragma omp target teams // { dg-error "is not a constant expression" } + i = 5; + return 0; +} + +constexpr int +f7 () +{ + int i = 0; +#pragma omp target data map(tofrom:i) // { dg-error "is not a constant expression" } + i = 5; + return 0; +} + +constexpr int +f8 () +{ + int i = 0; +#pragma omp target // { dg-error "is not a constant expression" } + i = 5; + return 0; +} + +constexpr int +f9 () +{ + int i = 0; +#pragma omp sections // { dg-error "is not a constant expression" } + { +#pragma omp section + i = 5; + } + return 0; +} + +constexpr int +f10 () +{ + int i = 0; +#pragma omp ordered // { dg-error "is not a constant expression" } + i = 1; + return 0; +} + +constexpr int +f11 () +{ + int i = 0; +#pragma omp critical // { dg-error "is not a constant expression" } + i = 1; + return 0; +} + +constexpr int +f12 () +{ + int i = 0; +#pragma omp single // { dg-error "is not a constant expression" } + i = 1; + return 0; +} + +constexpr int +f13 () +{ + int i = 0; +#pragma omp master // { dg-error "is not a constant expression" } + i = 1; + return 0; +} + +constexpr int +f14 () +{ + int i = 0; +#pragma omp taskgroup // { dg-error "is not a constant expression" } + i = 1; + return 0; +} + +constexpr int +f15 () +{ + int i = 0; +#pragma omp target update to(i) // { dg-error "is not a constant expression" } + i = 1; + return 0; +} + +constexpr int +f16 () +{ + int i = 0; +#pragma omp target update to(i) // { dg-error "is not a constant expression" } + return 0; +} + +constexpr int +f17 () +{ + int i = 0; +#pragma omp target enter data map(to:i) // { dg-error "is not a constant expression" } + return 0; +} + +constexpr int +f18 () +{ + int i = 0; +#pragma omp target exit data map(from:i) // { dg-error "is not a constant expression" } + return 0; +}