Commit e998a6c8 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Fixed compiler crash during semantic analysis of recursive ASN.1 type (bug 550526)



Change-Id: I4522681ac615d6a1e49b5644abd758e3652d1aa5
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent b72cd98a
...@@ -3458,12 +3458,17 @@ namespace Common { ...@@ -3458,12 +3458,17 @@ namespace Common {
default: default:
// no need to generate coder functions for basic types, but this function // no need to generate coder functions for basic types, but this function
// is also used to determine codec-specific descriptor generation // is also used to determine codec-specific descriptor generation
return can_have_coding(coding); return can_have_coding(coding) == TTRUE;
} }
} }
void Type::set_gen_coder_functions(MessageEncodingType_t coding) void Type::set_gen_coder_functions(MessageEncodingType_t coding)
{ {
if (is_asn1() && !checked) {
// probably a recursive ASN.1 type
// this function will be called again after the type is checked
return;
}
// TODO: this should also influence type descriptor generation // TODO: this should also influence type descriptor generation
switch (coding) { switch (coding) {
case CT_BER: case CT_BER:
...@@ -3528,19 +3533,27 @@ namespace Common { ...@@ -3528,19 +3533,27 @@ namespace Common {
} }
if (built_in_coding != CT_CUSTOM && built_in_coding != CT_PER) { if (built_in_coding != CT_CUSTOM && built_in_coding != CT_PER) {
if (get_type_refd_last()->can_have_coding(built_in_coding)) { switch (get_type_refd_last()->can_have_coding(built_in_coding)) {
case TTRUE: {
coding_t* new_coding = new coding_t; coding_t* new_coding = new coding_t;
new_coding->built_in = TRUE; new_coding->built_in = TRUE;
new_coding->modifier = modifier; new_coding->modifier = modifier;
new_coding->built_in_coding = built_in_coding; new_coding->built_in_coding = built_in_coding;
coding_table.add(new_coding); coding_table.add(new_coding);
get_type_refd_last()->set_gen_coder_functions(built_in_coding); get_type_refd_last()->set_gen_coder_functions(built_in_coding);
} break; }
else if (!silent) { case TFALSE:
// TODO: if an ASN.1 type cannot have a specific encoding, if (!silent) {
// it shouldn't be given that encoding in 'Type::chk_encodings' // TODO: if an ASN.1 type cannot have a specific encoding,
warning("Type `%s' cannot have %s encoding. Encode attribute ignored.", // it shouldn't be given that encoding in 'Type::chk_encodings'
get_typename().c_str(), get_encoding_name(built_in_coding)); warning("Type `%s' cannot have %s encoding. Encode attribute ignored.",
get_typename().c_str(), get_encoding_name(built_in_coding));
}
break;
case TUNKNOWN:
// do nothing, parts of the type are unchecked
// this function will be called later after the type has been checked
break;
} }
} }
else { else {
...@@ -3689,11 +3702,15 @@ namespace Common { ...@@ -3689,11 +3702,15 @@ namespace Common {
return t_parent; return t_parent;
} }
bool Type::can_have_coding(MessageEncodingType_t coding) tribool Type::can_have_coding(MessageEncodingType_t coding)
{ {
if (is_asn1() && !checked) {
// the type isn't fully checked yet
return TUNKNOWN;
}
// this helps avoid infinite recursions in self-referencing types // this helps avoid infinite recursions in self-referencing types
if (RecursionTracker::is_happening(this)) { if (RecursionTracker::is_happening(this)) {
return true; return TTRUE;
} }
RecursionTracker tracker(this); RecursionTracker tracker(this);
...@@ -3705,24 +3722,24 @@ namespace Common { ...@@ -3705,24 +3722,24 @@ namespace Common {
(coding == CT_XER && !enable_xer()) || (coding == CT_XER && !enable_xer()) ||
(coding == CT_JSON && !enable_json()) || (coding == CT_JSON && !enable_json()) ||
(coding == CT_OER && !enable_oer())) { (coding == CT_OER && !enable_oer())) {
return false; return TFALSE;
} }
// BER encoding is handled by 'has_encoding' // BER encoding is handled by 'has_encoding'
if (coding == CT_BER) { if (coding == CT_BER) {
return has_encoding(CT_BER); return has_encoding(CT_BER) ? TTRUE: TFALSE;
} }
// XER encoding for ASN.1 types can only be enabled by a compiler option // XER encoding for ASN.1 types can only be enabled by a compiler option
if (coding == CT_XER && !asn1_xer && is_asn1()) { if (coding == CT_XER && !asn1_xer && is_asn1()) {
return false; return TFALSE;
} }
// optimization: if it already has the encoding set, then the answer is true // optimization: if it already has the encoding set, then the answer is true
for (size_t i = 0; i < coding_table.size(); ++i) { for (size_t i = 0; i < coding_table.size(); ++i) {
if (coding_table[i]->built_in && if (coding_table[i]->built_in &&
coding_table[i]->built_in_coding == coding) { coding_table[i]->built_in_coding == coding) {
return true; return TTRUE;
} }
} }
...@@ -3738,15 +3755,16 @@ namespace Common { ...@@ -3738,15 +3755,16 @@ namespace Common {
// all field types must be able to have the specified encoding // all field types must be able to have the specified encoding
for (size_t i = 0; i < get_nof_comps(); ++i) { for (size_t i = 0; i < get_nof_comps(); ++i) {
Type* field_type = get_comp_byIndex(i)->get_type()->get_type_refd_last(); Type* field_type = get_comp_byIndex(i)->get_type()->get_type_refd_last();
if (!field_type->can_have_coding(coding)) { tribool tb = field_type->can_have_coding(coding);
return false; if (tb != TTRUE) {
return tb;
} }
} }
return true; return TTRUE;
case T_ARRAY: case T_ARRAY:
if (coding != CT_JSON) { if (coding != CT_JSON) {
return false; // arrays can only have JSON encoding return TFALSE; // arrays can only have JSON encoding
} }
// else fall through // else fall through
case T_SEQOF: case T_SEQOF:
...@@ -3769,9 +3787,9 @@ namespace Common { ...@@ -3769,9 +3787,9 @@ namespace Common {
case T_CSTR: case T_CSTR:
case T_USTR: case T_USTR:
case T_ENUM_T: case T_ENUM_T:
return true; return TTRUE;
default: default:
return false; return TFALSE;
} }
case CT_TEXT: case CT_TEXT:
...@@ -3783,9 +3801,9 @@ namespace Common { ...@@ -3783,9 +3801,9 @@ namespace Common {
case T_CSTR: case T_CSTR:
case T_USTR: case T_USTR:
case T_ENUM_T: case T_ENUM_T:
return true; return TTRUE;
default: default:
return false; return TFALSE;
} }
case CT_XER: case CT_XER:
...@@ -3802,9 +3820,9 @@ namespace Common { ...@@ -3802,9 +3820,9 @@ namespace Common {
case T_CSTR: case T_CSTR:
case T_USTR: case T_USTR:
case T_ENUM_T: case T_ENUM_T:
return true; // TODO: what about T_ERROR? return TTRUE; // TODO: what about T_ERROR?
default: default:
return false; return TFALSE;
} }
case CT_JSON: case CT_JSON:
...@@ -3837,9 +3855,9 @@ namespace Common { ...@@ -3837,9 +3855,9 @@ namespace Common {
case T_ANY: case T_ANY:
case T_ENUM_T: case T_ENUM_T:
case T_ENUM_A: case T_ENUM_A:
return true; // TODO: what about T_ERROR? return TTRUE; // TODO: what about T_ERROR?
default: default:
return false; return TFALSE;
} }
case CT_OER: case CT_OER:
...@@ -3869,9 +3887,9 @@ namespace Common { ...@@ -3869,9 +3887,9 @@ namespace Common {
case T_SEQOF: case T_SEQOF:
case T_EXTERNAL: case T_EXTERNAL:
case T_OBJECTDESCRIPTOR: case T_OBJECTDESCRIPTOR:
return true; return TTRUE;
default: default:
return false; return TFALSE;
} }
default: default:
FATAL_ERROR("Type::can_have_coding"); FATAL_ERROR("Type::can_have_coding");
...@@ -6585,7 +6603,7 @@ namespace Common { ...@@ -6585,7 +6603,7 @@ namespace Common {
// types need an 'encode' attribute for user-defined codecs // types need an 'encode' attribute for user-defined codecs
return false; return false;
} }
return last->can_have_coding(encoding_type); return last->can_have_coding(encoding_type) == TTRUE;
} }
// legacy codec handling, plus BER and PER encoding in both cases // legacy codec handling, plus BER and PER encoding in both cases
static memoizer memory; static memoizer memory;
......
...@@ -699,8 +699,10 @@ namespace Common { ...@@ -699,8 +699,10 @@ namespace Common {
const vector<coding_t>& get_coding_table() const { return coding_table; } const vector<coding_t>& get_coding_table() const { return coding_table; }
/** Returns whether this type can have the specified encoding. /** Returns whether this type can have the specified encoding.
* (Returns 'unknown' if the type is part of an ASN.1 structure that
* hasn't been fully checked yet.)
* Only used with new codec handling. */ * Only used with new codec handling. */
bool can_have_coding(MessageEncodingType_t coding); tribool can_have_coding(MessageEncodingType_t coding);
/** Checks whether the type itself or one of its fields/elements is a /** Checks whether the type itself or one of its fields/elements is a
* component or default type. Recursive. */ * component or default type. Recursive. */
......
Bug550526
Bug550526.exe
Bug550526*.cc
Bug550526*.hh
--/////////////////////////////////////////////////////////////////////////////
-- Copyright (c) 2000-2019 Ericsson Telecom AB
-- All rights reserved. This program and the accompanying materials
-- are made available under the terms of the Eclipse Public License v2.0
-- which accompanies this distribution, and is available at
-- https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
--
-- Contributors:
-- Baranyi, Botond
--
--/////////////////////////////////////////////////////////////////////////////
Bug550526
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Main ::= SEQUENCE
{
field1 CHOICE
{
alt1 INTEGER,
alt2 SEQUENCE SIZE (2..255) OF Main
},
field2 CHOICE
{
alt3 INTEGER,
alt4 NULL
}
}
END
##############################################################################
# Copyright (c) 2000-2019 Ericsson Telecom AB
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
#
# Contributors:
# Botond, Baranyi
#
##############################################################################
TOPDIR := ../..
include $(TOPDIR)/Makefile.regression
.PHONY: all clean dep
TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
ASN1_MODULES = Bug550526.asn
GENERATED_SOURCES = $(ASN1_MODULES:.asn=.cc)
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
ifdef CODE_SPLIT
GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc))
else ifdef SPLIT_TO_SLICES
POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
GENERATED_SOURCES += $(GENERATED_SOURCES2)
endif
OBJECTS = $(GENERATED_SOURCES:.cc=.o)
TARGET = Bug550526$(EXESUFFIX)
all: $(TARGET)
$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
-L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(ASN1_MODULES)
$(TTCN3_COMPILER) $(COMPILER_FLAGS) $^
clean distclean:
$(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
$(GENERATED_SOURCES) compile *.log
dep: $(GENERATED_SOURCES)
makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
...@@ -30,7 +30,7 @@ CODIRS := dynamicTemplate styleGuide topLevelPdu \ ...@@ -30,7 +30,7 @@ CODIRS := dynamicTemplate styleGuide topLevelPdu \
defaultParamUsageBeforeDecl deterministic readFromFile \ defaultParamUsageBeforeDecl deterministic readFromFile \
asn1_hyphen nameClash portTranslation UntaggedOnTopLevelUnionSwitch \ asn1_hyphen nameClash portTranslation UntaggedOnTopLevelUnionSwitch \
typeDescrGenWIthNoXER languageSpec asn1_opentype openTypeXER \ typeDescrGenWIthNoXER languageSpec asn1_opentype openTypeXER \
asnStringSubtypes componentParameter realtimeKeywords asnStringSubtypes componentParameter realtimeKeywords Bug550526
ifdef DYN ifdef DYN
CODIRS += mfgen-xsd CODIRS += mfgen-xsd
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment