From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by sourceware.org (Postfix) with ESMTPS id 24B123858D39; Sun, 26 Dec 2021 20:09:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 24B123858D39 Received: by mail-wm1-x32e.google.com with SMTP id l4so8570434wmq.3; Sun, 26 Dec 2021 12:09:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:mime-version:subject:message-id:date:cc:to; bh=01jeo+dEqFY5/jjEVnwmxPlZYRlt+q//Mt1WgMYJu/o=; b=sjW4RlQma8LkYqaxjY/M5t8/QtWx/hUHPcPrNHdMky+NVV+GVrG1v+AApuzYfGPin+ 1Usw89W+pYvGO951Gm/llcqQ4II2DPu8PZCmlRGJvvRKAbFEqw+0hflKnvCTJI4EbDI1 08zHez3tbTGPAQI2Of5SUUq9tzgeeAqpKRCc7xZ+4ASbT926DuCzISnCxHDFC4n/v8fz hFuNMuEOcnpmvyNOcjp7veaskpclCNvTerDu0pKOJp6OSKgq9IybQobqFx8Kc8RO6lYy gwCvRH3JH95zc9d3OoFJqxK41sD82CMsXbgPIMUP8ESNB1vxzMMCY3QRwhcFSoVhP8si qkaA== X-Gm-Message-State: AOAM533++2Zh+TVOkaTJZMulUbhldee8GndnDyyKGNo0evEnoImZm+iA OYALEEm96x+/U21La5pwsAhvKBguO04= X-Google-Smtp-Source: ABdhPJyV4FBfLtRXmfvvbCR2+d6D3wWw1QWyvFxRJJfVO5WabNN8EtmR5LnEp825eDb/DRv/55krlg== X-Received: by 2002:a05:600c:600c:: with SMTP id az12mr10900296wmb.86.1640549390432; Sun, 26 Dec 2021 12:09:50 -0800 (PST) Received: from smtpclient.apple ([2a01:e34:ec28:8cb0:bdfc:aa2b:ce73:acd2]) by smtp.gmail.com with ESMTPSA id v1sm15544628wru.45.2021.12.26.12.09.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Dec 2021 12:09:49 -0800 (PST) From: FX Content-Type: multipart/mixed; boundary="Apple-Mail=_D01D1E31-8054-4546-87BF-E6E33F65DD35" Mime-Version: 1.0 (Mac OS X Mail 15.0 \(3693.40.0.1.81\)) Subject: [PATCH] Emit correct types for CHARACTER(C_CHAR), VALUE Message-Id: <0CC6F1F8-D575-462E-90A7-0D24880C0022@gmail.com> Date: Sun, 26 Dec 2021 21:09:49 +0100 Cc: gcc-patches@gcc.gnu.org To: fortran@gcc.gnu.org X-Mailer: Apple Mail (2.3693.40.0.1.81) X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: fortran@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Fortran mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Dec 2021 20:09:53 -0000 --Apple-Mail=_D01D1E31-8054-4546-87BF-E6E33F65DD35 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi, I=E2=80=99ve spent many hours going down a rabbit hole, namely that we = emit incorrect types for C interoperable procedure parameters of type = CHARACTER(C_CHAR), VALUE. The full details can be found here: = https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D103828 I will try here to = be as brief as I can. This bug manifests on the new target aarche64-apple-darwin, and there = only if a CHARACTER(C_CHAR), VALUE argument is the 11th (or greater) = argument to the function. Then, we would pass it as a 32-bit value, = instead of an 8-bit value (as should a char). The front-end emits the = wrong type information about the argument, but it turns out for all = other targets this simply does not matter, due to their ABI. Interoperable CHARACTER(C_CHAR), VALUE arguments are weird, because deep = down they=E2=80=99re not actually character types (in the Fortran sense = of the word), i.e. arrays, but scalar C char (i.e., integers!). So = they=E2=80=99ve always been kind-of second class citizens in the = front-end. A function was introduced in 2007 that basically patches = their type on the fly: gfc_conv_scalar_char_value(). The problem is that = function is simply wrong. It says (from comments): /* Modify the tree type for scalar character dummy arguments of = bind(c) procedures if they are passed by value. The tree type for them = will be promoted to INTEGER_TYPE for the middle end, which appears to = be what C would do with characters passed by-value. The value = attribute implies the dummy is a scalar. */ The error is a misunderstanding of the C standard. char (and integer = types smaller than int) are promoted to int for argument passing in = unprototyped (old-school K&R) functions. In prototyped functions, they = are most definitely not promoted. Therefore, the function is wrong. More importantly, we can actually emit the right type much earlier in = the front-end, and we already have a place to do so, in gfc_sym_type(). = We already handle the result variables, but by-value arguments should = have the same type, so the fix is easy. In fact, once we emit the right type in gfc_sym_type(), we actually = never need to fix it up in gfc_conv_scalar_char_value(). Removing the = hack, I decided to leave it as a series of assertions, because we have = seen in the past that this case is difficult to catch, and can easily = regress due to changes elsewhere in the front-end. Then, once the hack is removed, it becomes clear that the two callers of = gfc_conv_scalar_char_value() expected different things from it: it=E2=80=99= s called from generate_local_decl() to hack the sym->backend_decl; and = it=E2=80=99s called from gfc_conv_procedure_call() for its true purpose, = as a real conv_* function. For the first case, we can inline the checks = (which have replaced the hack) into the caller in generate_local_decl(). = Once only the second use case remains, we can make the function local to = that file (make static, remove gfc_ prefix). The patch comes with a couple of extra testcases, exercising the passing = of char by value, and as integer, and their interoperability. It was regtested on x86_64-pc-gnu-linux, on aarch64-apple-darwin = (because its ABI is picky). OK to commit? FX --Apple-Mail=_D01D1E31-8054-4546-87BF-E6E33F65DD35 Content-Disposition: attachment; filename=0001-Fortran-Emit-correct-types-for-CHARACTER-C_CHAR-VALU.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Fortran-Emit-correct-types-for-CHARACTER-C_CHAR-VALU.patch" Content-Transfer-Encoding: quoted-printable =46rom=20f97bcd4044e032954f3a80479d1f1e5204d2d649=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Francois-Xavier=20Coudert=20= =0ADate:=20Sun,=2026=20Dec=202021=2020:18:01=20= +0100=0ASubject:=20[PATCH]=20Fortran:=20Emit=20correct=20types=20for=20= CHARACTER(C_CHAR),=20VALUE=0A=20arguments=0A=0AMake=20the=20front-end=20= emit=20the=20right=20type=20for=20CHARACTER(C_CHAR),=20VALUE=0Aarguments=20= to=20BIND(C)=20procedures.=20They=20are=20scalar=20integers=20of=20C=20= type=0Achar,=20and=20should=20be=20emitted=20as=20such.=20They=20are=20= not=20strings=20or=20arrays,=0Aand=20are=20not=20promoted=20to=20C=20= int,=20either.=0A=0Agcc/fortran/ChangeLog:=0A=0A=09PR=20fortran/103828=0A= =09*=20trans-decl.c=20(generate_local_decl):=20Do=20not=20call=0A=09= gfc_conv_scalar_char_value(),=20but=20check=20the=20type=20tree.=0A=09*=20= trans-expr.c=20(gfc_conv_scalar_char_value):=20Rename=20to=0A=09= conv_scalar_char_value,=20do=20not=20alter=20type=20tree.=0A=09= (gfc_conv_procedure_call):=20Adjust=20call=20to=20renamed=0A=09= conv_scalar_char_value()=20function.=0A=09*=20trans-types.c=20= (gfc_sym_type):=20Take=20care=20of=0A=09CHARACTER(C_CHAR),=20VALUE=20= arguments.=0A=09*=20trans.h=20(gfc_conv_scalar_char_value):=20Remove=20= prototype.=0A=0Agcc/testsuite/ChangeLog:=0A=0A=09PR=20fortran/103828=0A=09= *=20gfortran.dg/c_char_tests_3.f90:=20New=20file.=0A=09*=20= gfortran.dg/c_char_tests_3_c.c:=20New=20file.=0A=09*=20= gfortran.dg/c_char_tests_4.f90:=20New=20file.=0A=09*=20= gfortran.dg/c_char_tests_5.f90:=20New=20file.=0A---=0A=20= gcc/fortran/trans-decl.c=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20|=2017=20++--=0A=20gcc/fortran/trans-expr.c=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=2086=20= ++++++++-----------=0A=20gcc/fortran/trans-types.c=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20|=20=202=20+-=0A=20= gcc/fortran/trans.h=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20|=20=201=20-=0A=20= gcc/testsuite/gfortran.dg/c_char_tests_3.f90=20|=2051=20+++++++++++=0A=20= gcc/testsuite/gfortran.dg/c_char_tests_3_c.c=20|=2016=20++++=0A=20= gcc/testsuite/gfortran.dg/c_char_tests_4.f90=20|=2090=20= ++++++++++++++++++++=0A=20gcc/testsuite/gfortran.dg/c_char_tests_5.f90=20= |=2049=20+++++++++++=0A=208=20files=20changed,=20255=20insertions(+),=20= 57=20deletions(-)=0A=20create=20mode=20100644=20= gcc/testsuite/gfortran.dg/c_char_tests_3.f90=0A=20create=20mode=20100644=20= gcc/testsuite/gfortran.dg/c_char_tests_3_c.c=0A=20create=20mode=20100644=20= gcc/testsuite/gfortran.dg/c_char_tests_4.f90=0A=20create=20mode=20100644=20= gcc/testsuite/gfortran.dg/c_char_tests_5.f90=0A=0Adiff=20--git=20= a/gcc/fortran/trans-decl.c=20b/gcc/fortran/trans-decl.c=0Aindex=20= cb7f684d52c..d288af5aa10=20100644=0A---=20a/gcc/fortran/trans-decl.c=0A= +++=20b/gcc/fortran/trans-decl.c=0A@@=20-6001,15=20+6001,20=20@@=20= generate_local_decl=20(gfc_symbol=20*=20sym)=0A=20=0A=20=20=20if=20= (sym->attr.dummy=20=3D=3D=201)=0A=20=20=20=20=20{=0A-=20=20=20=20=20=20= /*=20Modify=20the=20tree=20type=20for=20scalar=20character=20dummy=20= arguments=20of=20bind(c)=0A-=09=20procedures=20if=20they=20are=20passed=20= by=20value.=20=20The=20tree=20type=20for=20them=20will=0A-=09=20be=20= promoted=20to=20INTEGER_TYPE=20for=20the=20middle=20end,=20which=20= appears=20to=20be=0A-=09=20what=20C=20would=20do=20with=20characters=20= passed=20by-value.=20=20The=20value=20attribute=0A-=20=20=20=20=20=20=20=20= =20implies=20the=20dummy=20is=20a=20scalar.=20=20*/=0A+=20=20=20=20=20=20= /*=20The=20tree=20type=20for=20scalar=20character=20dummy=20arguments=20= of=20BIND(C)=0A+=09=20procedures,=20if=20they=20are=20passed=20by=20= value,=20should=20be=20unsigned=20char.=0A+=09=20The=20value=20attribute=20= implies=20the=20dummy=20is=20a=20scalar.=20=20*/=0A=20=20=20=20=20=20=20= if=20(sym->attr.value=20=3D=3D=201=20&&=20sym->backend_decl=20!=3D=20= NULL=0A=20=09=20=20&&=20sym->ts.type=20=3D=3D=20BT_CHARACTER=20&&=20= sym->ts.is_c_interop=0A=20=09=20=20&&=20sym->ns->proc_name=20!=3D=20NULL=20= &&=20sym->ns->proc_name->attr.is_bind_c)=0A-=09= gfc_conv_scalar_char_value=20(sym,=20NULL,=20NULL);=0A+=09{=0A+=09=20=20= /*=20We=20used=20to=20modify=20the=20tree=20here.=20Now=20it=20is=20done=20= earlier=20in=0A+=09=20=20=20=20=20the=20front-end,=20so=20we=20only=20= check=20it=20here=20to=20avoid=20regressions.=20=20*/=0A+=09=20=20= gcc_assert=20(TREE_CODE=20(TREE_TYPE=20(sym->backend_decl))=20=3D=3D=20= INTEGER_TYPE);=0A+=09=20=20gcc_assert=20(TYPE_UNSIGNED=20(TREE_TYPE=20= (sym->backend_decl))=20=3D=3D=201);=0A+=09=20=20gcc_assert=20= (TYPE_PRECISION=20(TREE_TYPE=20(sym->backend_decl))=20=3D=3D=20= CHAR_TYPE_SIZE);=0A+=09=20=20gcc_assert=20(DECL_BY_REFERENCE=20= (sym->backend_decl)=20=3D=3D=200);=0A+=09}=0A=20=0A=20=20=20=20=20=20=20= /*=20Unused=20procedure=20passed=20as=20dummy=20argument.=20=20*/=0A=20=20= =20=20=20=20=20if=20(sym->attr.flavor=20=3D=3D=20FL_PROCEDURE)=0Adiff=20= --git=20a/gcc/fortran/trans-expr.c=20b/gcc/fortran/trans-expr.c=0Aindex=20= e413b2d7a1f..80c669f50fb=20100644=0A---=20a/gcc/fortran/trans-expr.c=0A= +++=20b/gcc/fortran/trans-expr.c=0A@@=20-41,6=20+41,7=20@@=20along=20= with=20GCC;=20see=20the=20file=20COPYING3.=20=20If=20not=20see=0A=20= #include=20"trans-stmt.h"=0A=20#include=20"dependency.h"=0A=20#include=20= "gimplify.h"=0A+#include=20"tm.h"=09=09/*=20For=20CHAR_TYPE_SIZE.=20=20= */=0A=20=0A=20=0A=20/*=20Calculate=20the=20number=20of=20characters=20in=20= a=20string.=20=20*/=0A@@=20-3972,63=20+3973,50=20@@=20= gfc_string_to_single_character=20(tree=20len,=20tree=20str,=20int=20= kind)=0A=20}=0A=20=0A=20=0A-void=0A-gfc_conv_scalar_char_value=20= (gfc_symbol=20*sym,=20gfc_se=20*se,=20gfc_expr=20**expr)=0A+static=20= void=0A+conv_scalar_char_value=20(gfc_symbol=20*sym,=20gfc_se=20*se,=20= gfc_expr=20**expr)=0A=20{=0A+=20=20gcc_assert=20(expr);=0A=20=0A+=20=20= /*=20We=20used=20to=20modify=20the=20tree=20here.=20Now=20it=20is=20done=20= earlier=20in=0A+=20=20=20=20=20the=20front-end,=20so=20we=20only=20check=20= it=20here=20to=20avoid=20regressions.=20=20*/=0A=20=20=20if=20= (sym->backend_decl)=0A=20=20=20=20=20{=0A-=20=20=20=20=20=20/*=20This=20= becomes=20the=20nominal_type=20in=0A-=09=20= function.c:assign_parm_find_data_types.=20=20*/=0A-=20=20=20=20=20=20= TREE_TYPE=20(sym->backend_decl)=20=3D=20unsigned_char_type_node;=0A-=20=20= =20=20=20=20/*=20This=20becomes=20the=20passed_type=20in=0A-=09=20= function.c:assign_parm_find_data_types.=20=20C=20promotes=20char=20to=0A= -=09=20integer=20for=20argument=20passing.=20=20*/=0A-=20=20=20=20=20=20= DECL_ARG_TYPE=20(sym->backend_decl)=20=3D=20unsigned_type_node;=0A-=0A-=20= =20=20=20=20=20DECL_BY_REFERENCE=20(sym->backend_decl)=20=3D=200;=0A+=20=20= =20=20=20=20gcc_assert=20(TREE_CODE=20(TREE_TYPE=20(sym->backend_decl))=20= =3D=3D=20INTEGER_TYPE);=0A+=20=20=20=20=20=20gcc_assert=20(TYPE_UNSIGNED=20= (TREE_TYPE=20(sym->backend_decl))=20=3D=3D=201);=0A+=20=20=20=20=20=20= gcc_assert=20(TYPE_PRECISION=20(TREE_TYPE=20(sym->backend_decl))=20=3D=3D=20= CHAR_TYPE_SIZE);=0A+=20=20=20=20=20=20gcc_assert=20(DECL_BY_REFERENCE=20= (sym->backend_decl)=20=3D=3D=200);=0A=20=20=20=20=20}=0A=20=0A-=20=20if=20= (expr=20!=3D=20NULL)=0A+=20=20/*=20If=20we=20have=20a=20constant=20= character=20expression,=20make=20it=20into=20an=0A+=20=20=20=20=20=20= integer=20of=20type=20C=20char.=20=20*/=0A+=20=20if=20= ((*expr)->expr_type=20=3D=3D=20EXPR_CONSTANT)=0A=20=20=20=20=20{=0A-=20=20= =20=20=20=20/*=20If=20we=20have=20a=20constant=20character=20expression,=20= make=20it=20into=20an=0A-=09=20integer.=20=20*/=0A-=20=20=20=20=20=20if=20= ((*expr)->expr_type=20=3D=3D=20EXPR_CONSTANT)=0A-=20=20=20=20=20=20=20=20= {=0A-=09=20=20gfc_typespec=20ts;=0A-=20=20=20=20=20=20=20=20=20=20= gfc_clear_ts=20(&ts);=0A+=20=20=20=20=20=20gfc_typespec=20ts;=0A+=20=20=20= =20=20=20gfc_clear_ts=20(&ts);=0A=20=0A-=09=20=20*expr=20=3D=20= gfc_get_int_expr=20(gfc_default_integer_kind,=20NULL,=0A-=09=09=09=09=20=20= =20=20(int)(*expr)->value.character.string[0]);=0A-=09=20=20if=20= ((*expr)->ts.kind=20!=3D=20gfc_c_int_kind)=0A-=09=20=20=20=20{=0A-=20=20=09= =20=20=20=20=20=20/*=20The=20expr=20needs=20to=20be=20compatible=20with=20= a=20C=20int.=20=20If=20the=0A-=09=09=20conversion=20fails,=20then=20the=20= 2=20causes=20an=20ICE.=20=20*/=0A-=09=20=20=20=20=20=20ts.type=20=3D=20= BT_INTEGER;=0A-=09=20=20=20=20=20=20ts.kind=20=3D=20gfc_c_int_kind;=0A-=09= =20=20=20=20=20=20gfc_convert_type=20(*expr,=20&ts,=202);=0A-=09=20=20=20= =20}=0A+=20=20=20=20=20=20*expr=20=3D=20gfc_get_int_expr=20= (gfc_default_character_kind,=20NULL,=0A+=09=09=09=09= (*expr)->value.character.string[0]);=0A+=20=20=20=20}=0A+=20=20else=20if=20= (se=20!=3D=20NULL=20&&=20(*expr)->expr_type=20=3D=3D=20EXPR_VARIABLE)=0A= +=20=20=20=20{=0A+=20=20=20=20=20=20if=20((*expr)->ref=20=3D=3D=20NULL)=0A= +=09{=0A+=09=20=20se->expr=20=3D=20gfc_string_to_single_character=0A+=09=20= =20=20=20(build_int_cst=20(integer_type_node,=201),=0A+=09=20=20=20=20=20= =20gfc_build_addr_expr=20(gfc_get_pchar_type=20((*expr)->ts.kind),=0A+=09= =09=09=09=20=20gfc_get_symbol_decl=0A+=09=09=09=09=20=20= ((*expr)->symtree->n.sym)),=0A+=09=20=20=20=20=20=20(*expr)->ts.kind);=0A= =20=09}=0A-=20=20=20=20=20=20else=20if=20(se=20!=3D=20NULL=20&&=20= (*expr)->expr_type=20=3D=3D=20EXPR_VARIABLE)=0A-=20=20=20=20=20=20=20=20= {=0A-=09=20=20if=20((*expr)->ref=20=3D=3D=20NULL)=0A-=09=20=20=20=20{=0A= -=09=20=20=20=20=20=20se->expr=20=3D=20gfc_string_to_single_character=0A= -=09=09(build_int_cst=20(integer_type_node,=201),=0A-=09=09=20= gfc_build_addr_expr=20(gfc_get_pchar_type=20((*expr)->ts.kind),=0A-=09=09= =09=09=20=20=20=20=20=20gfc_get_symbol_decl=0A-=09=09=09=09=20=20=20=20=20= =20((*expr)->symtree->n.sym)),=0A-=09=09=20(*expr)->ts.kind);=0A-=09=20=20= =20=20}=0A-=09=20=20else=0A-=09=20=20=20=20{=0A-=09=20=20=20=20=20=20= gfc_conv_variable=20(se,=20*expr);=0A-=09=20=20=20=20=20=20se->expr=20=3D=20= gfc_string_to_single_character=0A-=09=09(build_int_cst=20= (integer_type_node,=201),=0A-=09=09=20gfc_build_addr_expr=20= (gfc_get_pchar_type=20((*expr)->ts.kind),=0A-=09=09=09=09=20=20=20=20=20=20= se->expr),=0A-=09=09=20(*expr)->ts.kind);=0A-=09=20=20=20=20}=0A+=20=20=20= =20=20=20else=0A+=09{=0A+=09=20=20gfc_conv_variable=20(se,=20*expr);=0A+=09= =20=20se->expr=20=3D=20gfc_string_to_single_character=0A+=09=20=20=20=20= (build_int_cst=20(integer_type_node,=201),=0A+=09=20=20=20=20=20=20= gfc_build_addr_expr=20(gfc_get_pchar_type=20((*expr)->ts.kind),=0A+=09=09= =09=09=20=20se->expr),=0A+=09=20=20=20=20=20=20(*expr)->ts.kind);=0A=20=09= }=0A=20=20=20=20=20}=0A=20}=0A@@=20-6341,7=20+6329,7=20@@=20= gfc_conv_procedure_call=20(gfc_se=20*=20se,=20gfc_symbol=20*=20sym,=0A=20= =09=09=20=20=20=20=20=20&&=20fsym->ns->proc_name->attr.is_bind_c)=0A=20=09= =09=20=20=20=20{=0A=20=09=09=20=20=20=20=20=20parmse.expr=20=3D=20NULL;=0A= -=09=09=20=20=20=20=20=20gfc_conv_scalar_char_value=20(fsym,=20&parmse,=20= &e);=0A+=09=09=20=20=20=20=20=20conv_scalar_char_value=20(fsym,=20= &parmse,=20&e);=0A=20=09=09=20=20=20=20=20=20if=20(parmse.expr=20=3D=3D=20= NULL)=0A=20=09=09=09gfc_conv_expr=20(&parmse,=20e);=0A=20=09=09=20=20=20=20= }=0Adiff=20--git=20a/gcc/fortran/trans-types.c=20= b/gcc/fortran/trans-types.c=0Aindex=20eec4aa6f5fc..6262d52657f=20100644=0A= ---=20a/gcc/fortran/trans-types.c=0A+++=20b/gcc/fortran/trans-types.c=0A= @@=20-2262,7=20+2262,7=20@@=20gfc_sym_type=20(gfc_symbol=20*=20sym,=20= bool=20is_bind_c)=0A=20=0A=20=20=20if=20(sym->ts.type=20=3D=3D=20= BT_CHARACTER=0A=20=20=20=20=20=20=20&&=20((sym->attr.function=20&&=20= sym->attr.is_bind_c)=0A-=09=20=20||=20(sym->attr.result=0A+=09=20=20||=20= ((sym->attr.result=20||=20sym->attr.value)=0A=20=09=20=20=20=20=20=20&&=20= sym->ns->proc_name=0A=20=09=20=20=20=20=20=20&&=20= sym->ns->proc_name->attr.is_bind_c)=0A=20=09=20=20||=20(sym->ts.deferred=20= &&=20(!sym->ts.u.cl=0Adiff=20--git=20a/gcc/fortran/trans.h=20= b/gcc/fortran/trans.h=0Aindex=2015012a336ff..f78d5025047=20100644=0A---=20= a/gcc/fortran/trans.h=0A+++=20b/gcc/fortran/trans.h=0A@@=20-508,7=20= +508,6=20@@=20void=20gfc_conv_expr_type=20(gfc_se=20*=20se,=20gfc_expr=20= *,=20tree);=0A=20tree=20gfc_get_character_len_in_bytes=20(tree);=0A=20= tree=20gfc_conv_scalar_to_descriptor=20(gfc_se=20*,=20tree,=20= symbol_attribute);=0A=20tree=20= gfc_get_ultimate_alloc_ptr_comps_caf_token=20(gfc_se=20*,=20gfc_expr=20= *);=0A-void=20gfc_conv_scalar_char_value=20(gfc_symbol=20*sym,=20gfc_se=20= *se,=20gfc_expr=20**expr);=0A=20tree=20gfc_string_to_single_character=20= (tree=20len,=20tree=20str,=20int=20kind);=0A=20tree=20= gfc_get_tree_for_caf_expr=20(gfc_expr=20*);=0A=20void=20= gfc_get_caf_token_offset=20(gfc_se*,=20tree=20*,=20tree=20*,=20tree,=20= tree,=20gfc_expr=20*);=0Adiff=20--git=20= a/gcc/testsuite/gfortran.dg/c_char_tests_3.f90=20= b/gcc/testsuite/gfortran.dg/c_char_tests_3.f90=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..9fc07144ed0=0A---=20/dev/null=0A+++=20= b/gcc/testsuite/gfortran.dg/c_char_tests_3.f90=0A@@=20-0,0=20+1,51=20@@=0A= +!=20{=20dg-do=20run=20}=0A+!=20{=20dg-additional-sources=20= c_char_tests_3_c.c=20}=0A+!=0A+!=20PR=20fortran/103828=0A+!=20Check=20= that=20we=20can=20pass=20many=20function=20args=20as=20C=20char,=20which=20= are=20interoperable=0A+!=20with=20both=20INTEGER(C_SIGNED_CHAR)=20and=20= CHARACTER(C_CHAR).=0A+=0A+subroutine=20test_int=20(a,=20b,=20c,=20d,=20= e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o)=20bind(c)=0A+=20=20= use,=20intrinsic=20::=20iso_c_binding=0A+=20=20implicit=20none=0A+=20=20= integer(c_signed_char),=20value=20::=20a,=20b,=20c,=20d,=20e,=20f,=20g,=20= h,=20i,=20j,=20k,=20l,=20m,=20n,=20o=0A+=0A+=20=20if=20(a=20/=3D=20= iachar('a'))=20stop=201=0A+=20=20if=20(b=20/=3D=20iachar('b'))=20stop=20= 2=0A+=20=20if=20(c=20/=3D=20iachar('c'))=20stop=203=0A+=20=20if=20(d=20= /=3D=20iachar('d'))=20stop=204=0A+=20=20if=20(e=20/=3D=20iachar('e'))=20= stop=205=0A+=20=20if=20(f=20/=3D=20iachar('f'))=20stop=206=0A+=20=20if=20= (g=20/=3D=20iachar('g'))=20stop=207=0A+=20=20if=20(h=20/=3D=20= iachar('h'))=20stop=208=0A+=20=20if=20(i=20/=3D=20iachar('i'))=20stop=20= 9=0A+=20=20if=20(j=20/=3D=20iachar('j'))=20stop=2010=0A+=20=20if=20(k=20= /=3D=20iachar('k'))=20stop=2011=0A+=20=20if=20(l=20/=3D=20iachar('l'))=20= stop=2012=0A+=20=20if=20(m=20/=3D=20iachar('m'))=20stop=2013=0A+=20=20if=20= (n=20/=3D=20iachar('n'))=20stop=2014=0A+=20=20if=20(o=20/=3D=20= iachar('o'))=20stop=2015=0A+end=20subroutine=0A+=0A+subroutine=20= test_char=20(a,=20b,=20c,=20d,=20e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20= m,=20n,=20o)=20bind(c)=0A+=20=20use,=20intrinsic=20::=20iso_c_binding=0A= +=20=20implicit=20none=0A+=20=20character(kind=3Dc_char,=20len=3D1),=20= value=20::=20a,=20b,=20c,=20d,=20e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20= m,=20n,=20o=0A+=0A+=20=20if=20(a=20/=3D=20'a')=20stop=20101=0A+=20=20if=20= (b=20/=3D=20'b')=20stop=20102=0A+=20=20if=20(c=20/=3D=20'c')=20stop=20= 103=0A+=20=20if=20(d=20/=3D=20'd')=20stop=20104=0A+=20=20if=20(e=20/=3D=20= 'e')=20stop=20105=0A+=20=20if=20(f=20/=3D=20'f')=20stop=20106=0A+=20=20= if=20(g=20/=3D=20'g')=20stop=20107=0A+=20=20if=20(h=20/=3D=20'h')=20stop=20= 108=0A+=20=20if=20(i=20/=3D=20'i')=20stop=20109=0A+=20=20if=20(j=20/=3D=20= 'j')=20stop=20110=0A+=20=20if=20(k=20/=3D=20'k')=20stop=20111=0A+=20=20= if=20(l=20/=3D=20'l')=20stop=20112=0A+=20=20if=20(m=20/=3D=20'm')=20stop=20= 113=0A+=20=20if=20(n=20/=3D=20'n')=20stop=20114=0A+=20=20if=20(o=20/=3D=20= 'o')=20stop=20115=0A+end=20subroutine=0A+=0Adiff=20--git=20= a/gcc/testsuite/gfortran.dg/c_char_tests_3_c.c=20= b/gcc/testsuite/gfortran.dg/c_char_tests_3_c.c=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..1c86a549165=0A---=20/dev/null=0A+++=20= b/gcc/testsuite/gfortran.dg/c_char_tests_3_c.c=0A@@=20-0,0=20+1,16=20@@=0A= +void=20test_char=20(char,=20char,=20char,=20char,=20char,=0A+=09=09= char,=20char,=20char,=20char,=20char,=0A+=09=09char,=20char,=20char,=20= char,=20char);=0A+=0A+void=20test_int=20(char,=20char,=20char,=20char,=20= char,=0A+=09=20=20=20=20=20=20=20char,=20char,=20char,=20char,=20char,=0A= +=09=20=20=20=20=20=20=20char,=20char,=20char,=20char,=20char);=0A+=0A= +int=20main=20(void)=20{=0A+=20=20test_char=20('a',=20'b',=20'c',=20'd',=20= 'e',=0A+=09=20=20=20=20=20'f',=20'g',=20'h',=20'i',=20'j',=0A+=09=20=20=20= =20=20'k',=20'l',=20'm',=20'n',=20'o');=0A+=20=20test_int=20('a',=20'b',=20= 'c',=20'd',=20'e',=0A+=09=20=20=20=20'f',=20'g',=20'h',=20'i',=20'j',=0A= +=09=20=20=20=20'k',=20'l',=20'm',=20'n',=20'o');=0A+}=0Adiff=20--git=20= a/gcc/testsuite/gfortran.dg/c_char_tests_4.f90=20= b/gcc/testsuite/gfortran.dg/c_char_tests_4.f90=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..512948a2a3f=0A---=20/dev/null=0A+++=20= b/gcc/testsuite/gfortran.dg/c_char_tests_4.f90=0A@@=20-0,0=20+1,90=20@@=0A= +!=20{=20dg-do=20run=20}=0A+!=0A+!=20PR=20fortran/103828=0A+!=20Check=20= that=20we=20can=20pass=20many=20function=20args=20as=20C=20char,=20which=20= are=20interoperable=0A+!=20with=20both=20INTEGER(C_SIGNED_CHAR)=20and=20= CHARACTER(C_CHAR).=0A+=0A+program=20test=0A+=20=20use,=20intrinsic=20::=20= iso_c_binding,=20only=20:=20c_signed_char,=20c_char=0A+=20=20implicit=20= none=0A+=0A+=20=20interface=0A+=20=20=20=20!=20In=20order=20to=20perform=20= this=20test,=20we=20cheat=20and=20pretend=20to=20give=20each=20function=0A= +=20=20=20=20!=20the=20other=20one's=20prototype.=20It=20should=20still=20= work,=20because=20all=20arguments=0A+=20=20=20=20!=20are=20interoperable=20= with=20C=20char.=0A+=0A+=20=20=20=20subroutine=20test1=20(a,=20b,=20c,=20= d,=20e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o)=20bind(c,=20= name=3D'test_int')=0A+=20=20=20=20=20=20import=20c_char=0A+=20=20=20=20=20= =20character(kind=3Dc_char,=20len=3D1),=20value=20::=20a,=20b,=20c,=20d,=20= e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o=0A+=20=20=20=20end=20= subroutine=20test1=0A+=0A+=20=20=20=20subroutine=20test2=20(a,=20b,=20c,=20= d,=20e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o)=20bind(c,=20= name=3D'test_char')=0A+=20=20=20=20=20=20import=20c_signed_char=0A+=20=20= =20=20=20=20integer(kind=3Dc_signed_char),=20value=20::=20a,=20b,=20c,=20= d,=20e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o=0A+=20=20=20=20= end=20subroutine=20test2=0A+=0A+=20=20end=20interface=0A+=0A+=20=20call=20= test1('a',=20'b',=20'c',=20'd',=20'e',=20'f',=20'g',=20'h',=20'i',=20= 'j',=20'k',=20'l',=20'm',=20'n',=20'o')=0A+=20=20call=20test2(ichar('a',=20= kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= ichar('b',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20ichar('c',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20ichar('d',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20ichar('e',=20kind=3Dc_signed_char),=20&=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20ichar('f',=20kind=3Dc_signed_char),=20= &=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20ichar('g',=20= kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= ichar('h',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20ichar('i',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20ichar('j',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20= =20=20=20=20=20=20=20=20=20ichar('k',=20kind=3Dc_signed_char),=20&=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20ichar('l',=20kind=3Dc_signed_char),=20= &=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20ichar('m',=20= kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= ichar('n',=20kind=3Dc_signed_char),=20&=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20ichar('o',=20kind=3Dc_signed_char))=0A+=0A+end=20program=20test=0A= +=0A+subroutine=20test_int=20(a,=20b,=20c,=20d,=20e,=20f,=20g,=20h,=20i,=20= j,=20k,=20l,=20m,=20n,=20o)=20bind(c)=0A+=20=20use,=20intrinsic=20::=20= iso_c_binding,=20only=20:=20c_signed_char=0A+=20=20implicit=20none=0A+=20= =20integer(c_signed_char),=20value=20::=20a,=20b,=20c,=20d,=20e,=20f,=20= g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o=0A+=0A+=20=20if=20(a=20/=3D=20= iachar('a'))=20stop=201=0A+=20=20if=20(b=20/=3D=20iachar('b'))=20stop=20= 2=0A+=20=20if=20(c=20/=3D=20iachar('c'))=20stop=203=0A+=20=20if=20(d=20= /=3D=20iachar('d'))=20stop=204=0A+=20=20if=20(e=20/=3D=20iachar('e'))=20= stop=205=0A+=20=20if=20(f=20/=3D=20iachar('f'))=20stop=206=0A+=20=20if=20= (g=20/=3D=20iachar('g'))=20stop=207=0A+=20=20if=20(h=20/=3D=20= iachar('h'))=20stop=208=0A+=20=20if=20(i=20/=3D=20iachar('i'))=20stop=20= 9=0A+=20=20if=20(j=20/=3D=20iachar('j'))=20stop=2010=0A+=20=20if=20(k=20= /=3D=20iachar('k'))=20stop=2011=0A+=20=20if=20(l=20/=3D=20iachar('l'))=20= stop=2012=0A+=20=20if=20(m=20/=3D=20iachar('m'))=20stop=2013=0A+=20=20if=20= (n=20/=3D=20iachar('n'))=20stop=2014=0A+=20=20if=20(o=20/=3D=20= iachar('o'))=20stop=2015=0A+end=20subroutine=0A+=0A+subroutine=20= test_char=20(a,=20b,=20c,=20d,=20e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20= m,=20n,=20o)=20bind(c)=0A+=20=20use,=20intrinsic=20::=20iso_c_binding,=20= only=20:=20c_char=0A+=20=20implicit=20none=0A+=20=20= character(kind=3Dc_char,=20len=3D1),=20value=20::=20a,=20b,=20c,=20d,=20= e,=20f,=20g,=20h,=20i,=20j,=20k,=20l,=20m,=20n,=20o=0A+=0A+=20=20if=20(a=20= /=3D=20'a')=20stop=20101=0A+=20=20if=20(b=20/=3D=20'b')=20stop=20102=0A+=20= =20if=20(c=20/=3D=20'c')=20stop=20103=0A+=20=20if=20(d=20/=3D=20'd')=20= stop=20104=0A+=20=20if=20(e=20/=3D=20'e')=20stop=20105=0A+=20=20if=20(f=20= /=3D=20'f')=20stop=20106=0A+=20=20if=20(g=20/=3D=20'g')=20stop=20107=0A+=20= =20if=20(h=20/=3D=20'h')=20stop=20108=0A+=20=20if=20(i=20/=3D=20'i')=20= stop=20109=0A+=20=20if=20(j=20/=3D=20'j')=20stop=20110=0A+=20=20if=20(k=20= /=3D=20'k')=20stop=20111=0A+=20=20if=20(l=20/=3D=20'l')=20stop=20112=0A+=20= =20if=20(m=20/=3D=20'm')=20stop=20113=0A+=20=20if=20(n=20/=3D=20'n')=20= stop=20114=0A+=20=20if=20(o=20/=3D=20'o')=20stop=20115=0A+end=20= subroutine=0A+=0Adiff=20--git=20= a/gcc/testsuite/gfortran.dg/c_char_tests_5.f90=20= b/gcc/testsuite/gfortran.dg/c_char_tests_5.f90=0Anew=20file=20mode=20= 100644=0Aindex=2000000000000..c7a1c6e8c2b=0A---=20/dev/null=0A+++=20= b/gcc/testsuite/gfortran.dg/c_char_tests_5.f90=0A@@=20-0,0=20+1,49=20@@=0A= +!=20{=20dg-do=20run=20}=0A+!=20{=20dg-options=20"-fbackslash"=20}=0A+!=0A= +!=20PR=20fortran/103828=0A+!=20Check=20that=20we=20can=20C=20char=20= with=20non-ASCII=20values,=20which=20are=20interoperable=0A+!=20with=20= both=20INTEGER(C_SIGNED_CHAR)=20and=20CHARACTER(C_CHAR).=0A+=0A+program=20= test=0A+=20=20use,=20intrinsic=20::=20iso_c_binding,=20only=20:=20= c_signed_char,=20c_char=0A+=20=20implicit=20none=0A+=0A+=20=20interface=0A= +=20=20=20=20!=20In=20order=20to=20perform=20this=20test,=20we=20cheat=20= and=20pretend=20to=20give=20each=20function=0A+=20=20=20=20!=20the=20= other=20one's=20prototype.=20It=20should=20still=20work,=20because=20all=20= arguments=0A+=20=20=20=20!=20are=20interoperable=20with=20C=20char.=0A+=0A= +=20=20=20=20subroutine=20test1=20(a)=20bind(c,=20name=3D'test_int')=0A+=20= =20=20=20=20=20import=20c_char=0A+=20=20=20=20=20=20= character(kind=3Dc_char,=20len=3D1),=20value=20::=20a=0A+=20=20=20=20end=20= subroutine=20test1=0A+=0A+=20=20=20=20subroutine=20test2=20(a)=20bind(c,=20= name=3D'test_char')=0A+=20=20=20=20=20=20import=20c_signed_char=0A+=20=20= =20=20=20=20integer(kind=3Dc_signed_char),=20value=20::=20a=0A+=20=20=20=20= end=20subroutine=20test2=0A+=0A+=20=20end=20interface=0A+=0A+=20=20call=20= test1('\xA3')=0A+=20=20call=20test2(-93_c_signed_char)=0A+=0A+end=20= program=20test=0A+=0A+subroutine=20test_int=20(a)=20bind(c)=0A+=20=20= use,=20intrinsic=20::=20iso_c_binding,=20only=20:=20c_signed_char=0A+=20=20= implicit=20none=0A+=20=20integer(c_signed_char),=20value=20::=20a=0A+=0A= +=20=20if=20(a=20/=3D=20iachar('\xA3',=20kind=3Dc_signed_char))=20stop=20= 1=0A+end=20subroutine=0A+=0A+subroutine=20test_char=20(a)=20bind(c)=0A+=20= =20use,=20intrinsic=20::=20iso_c_binding,=20only=20:=20c_char=0A+=20=20= implicit=20none=0A+=20=20character(kind=3Dc_char,=20len=3D1),=20value=20= ::=20a=0A+=0A+=20=20if=20(a=20/=3D=20'\xA3')=20stop=20101=0A+end=20= subroutine=0A+=0A--=20=0A2.32.0=20(Apple=20Git-132)=0A=0A= --Apple-Mail=_D01D1E31-8054-4546-87BF-E6E33F65DD35--