Skip to content

Commit

Permalink
libiberty/
Browse files Browse the repository at this point in the history
	* cp-demangle.c (cplus_demangle_type): Fix function quals.
	(d_pointer_to_member_type): Simplify.
gcc/cp/
	* mangle.c (write_type): When writing a function type with
	function-cv-quals, don't add the unqualified type as a
	substitution candidate.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197460 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
jason committed Apr 4, 2013
1 parent ba12557 commit 862e5b6
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 46 deletions.
5 changes: 5 additions & 0 deletions gcc/common.opt
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,11 @@ Driver Undocumented
; 7: The version of the ABI that treats nullptr_t as a builtin type and
; corrects the mangling of lambdas in default argument scope.
; First selectable in G++ 4.8.
;
; 8: The version of the ABI that corrects the substitution behavior of
; function types with function-cv-qualifiers.
; First selectable in G++ 4.9.
;
; Additional positive integers will be assigned as new versions of
; the ABI become the default version of the ABI.
fabi-version=
Expand Down
6 changes: 6 additions & 0 deletions gcc/cp/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2013-04-03 Jason Merrill <jason@redhat.com>

* mangle.c (write_type): When writing a function type with
function-cv-quals, don't add the unqualified type as a
substitution candidate.

2013-04-03 Paolo Carlini <paolo.carlini@oracle.com>

PR c++/56815
Expand Down
12 changes: 10 additions & 2 deletions gcc/cp/mangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1897,8 +1897,16 @@ write_type (tree type)
tree t = TYPE_MAIN_VARIANT (type);
if (TREE_CODE (t) == FUNCTION_TYPE
|| TREE_CODE (t) == METHOD_TYPE)
t = build_ref_qualified_type (t, type_memfn_rqual (type));
write_type (t);
{
t = build_ref_qualified_type (t, type_memfn_rqual (type));
if (abi_version_at_least (8))
/* Avoid adding the unqualified function type as a substitution. */
write_function_type (t);
else
write_type (t);
}
else
write_type (t);
}
else if (TREE_CODE (type) == ARRAY_TYPE)
/* It is important not to use the TYPE_MAIN_VARIANT of TYPE here
Expand Down
11 changes: 11 additions & 0 deletions gcc/testsuite/g++.dg/abi/mangle62.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Before v8, we mistakenly treated an unqualified function type
// as a substitution candidate for a function type with function-cv-quals.
// Test for the conformant behavior.

// { dg-options -fabi-version=0 }

template <class T, class U> struct A { };
// { dg-final { scan-assembler "_Z1fP1AIKFvvEFvvEE" } }
void f (A<void()const, void()> *){}
// { dg-final { scan-assembler "_Z1gP1AIFvvEKFvvEE" } }
void g (A<void(), void()const> *){}
11 changes: 11 additions & 0 deletions gcc/testsuite/g++.dg/abi/mangle62a.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Before v8, we mistakenly treated an unqualified function type
// as a substitution candidate for a function type with function-cv-quals.
// Test for that for backward compatibility.

// { dg-options -fabi-version=7 }

template <class T, class U> struct A { };
// { dg-final { scan-assembler "_Z1fP1AIKFvvES0_E" } }
void f (A<void()const, void()> *){}
// { dg-final { scan-assembler "_Z1gP1AIFvvEKS0_E" } }
void g (A<void(), void()const> *){}
3 changes: 3 additions & 0 deletions libiberty/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
2013-04-03 Jason Merrill <jason@redhat.com>

* cp-demangle.c (cplus_demangle_type): Fix function quals.
(d_pointer_to_member_type): Simplify.

Demangle C++11 ref-qualifier.
* cp-demangle.c (d_ref_qualifier): New.
(d_nested_name, d_function_type): Use it.
Expand Down
71 changes: 29 additions & 42 deletions libiberty/cp-demangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -2198,8 +2198,16 @@ cplus_demangle_type (struct d_info *di)
pret = d_cv_qualifiers (di, &ret, 0);
if (pret == NULL)
return NULL;
*pret = cplus_demangle_type (di);
if (! *pret)
if (d_peek_char (di) == 'F')
{
/* cv-qualifiers before a function type apply to 'this',
so avoid adding the unqualified function type to
the substitution list. */
*pret = d_function_type (di);
}
else
*pret = cplus_demangle_type (di);
if (!*pret)
return NULL;
if ((*pret)->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
|| (*pret)->type == DEMANGLE_COMPONENT_REFERENCE_THIS)
Expand Down Expand Up @@ -2739,53 +2747,32 @@ d_pointer_to_member_type (struct d_info *di)
{
struct demangle_component *cl;
struct demangle_component *mem;
struct demangle_component **pmem;

if (! d_check_char (di, 'M'))
return NULL;

cl = cplus_demangle_type (di);

/* The ABI specifies that any type can be a substitution source, and
that M is followed by two types, and that when a CV-qualified
type is seen both the base type and the CV-qualified types are
substitution sources. The ABI also specifies that for a pointer
to a CV-qualified member function, the qualifiers are attached to
the second type. Given the grammar, a plain reading of the ABI
suggests that both the CV-qualified member function and the
non-qualified member function are substitution sources. However,
g++ does not work that way. g++ treats only the CV-qualified
member function as a substitution source. FIXME. So to work
with g++, we need to pull off the CV-qualifiers here, in order to
avoid calling add_substitution() in cplus_demangle_type(). But
for a CV-qualified member which is not a function, g++ does
follow the ABI, so we need to handle that case here by calling
d_add_substitution ourselves. */

pmem = d_cv_qualifiers (di, &mem, 1);
if (pmem == NULL)
return NULL;
*pmem = cplus_demangle_type (di);
if (*pmem == NULL)
if (cl == NULL)
return NULL;

if (pmem != &mem
&& ((*pmem)->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
|| (*pmem)->type == DEMANGLE_COMPONENT_REFERENCE_THIS))
{
/* Move the ref-qualifier outside the cv-qualifiers so that
they are printed in the right order. */
struct demangle_component *fn = d_left (*pmem);
d_left (*pmem) = mem;
mem = *pmem;
*pmem = fn;
}

if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
{
if (! d_add_substitution (di, mem))
return NULL;
}
/* The ABI says, "The type of a non-static member function is considered
to be different, for the purposes of substitution, from the type of a
namespace-scope or static member function whose type appears
similar. The types of two non-static member functions are considered
to be different, for the purposes of substitution, if the functions
are members of different classes. In other words, for the purposes of
substitution, the class of which the function is a member is
considered part of the type of function."
For a pointer to member function, this call to cplus_demangle_type
will end up adding a (possibly qualified) non-member function type to
the substitution table, which is not correct; however, the member
function type will never be used in a substitution, so putting the
wrong type in the substitution table is harmless. */

mem = cplus_demangle_type (di);
if (mem == NULL)
return NULL;

return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
}
Expand Down
4 changes: 2 additions & 2 deletions libiberty/testsuite/demangle-expected
Original file line number Diff line number Diff line change
Expand Up @@ -4273,8 +4273,8 @@ foo
#
--format=gnu-v3 --no-params
_Z1fIKFvvES0_Evv
void f<void () const, void ()>()
f<void () const, void ()>
void f<void () const, void () const>()
f<void () const, void () const>
#
--format=gnu-v3
_ZN4modc6parser8sequenceINS_9astParser13LocatedParserINS0_9ParserRefINS2_UlRNS2_16TokenParserInputEE_EEEEEINS0_14OptionalParserINS2_18ListParserTemplateILNS_6tokens5Token4TypeE4EXadL_ZNSD_Ut_13parenthesizedEEEE6ParserINS4_INS0_6ParserIS5_NS_3ast10ExpressionEEEEEEEEENSA_INS4_INS2_22OneOfKeywordsToTParserINSJ_5StyleEEEEEEENS0_14SequenceParserIS5_INS0_18ExactElementParserIS5_EENSA_ISM_EEEEENS0_14RepeatedParserINS4_INS0_15TransformParserINSU_IS5_INS4_INSP_INSJ_10Annotation12RelationshipEEEEESX_EEENS2_UlNS2_3LocES12_ONS_5MaybeISK_EEE19_EEEEELb0EEEEEENSU_INS0_17ExtractParserTypeIT_E9InputTypeEINS0_8MaybeRefIS1F_E4TypeEDpNS1I_IT0_E4TypeEEEEOS1F_DpOS1L_
Expand Down

0 comments on commit 862e5b6

Please sign in to comment.