Skip to content

Commit a1d419c

Browse files
committed
C++ front-end: Declarator to symbol conversion follows C implementation
Now attributes actually end up in the symbol table.
1 parent 3491634 commit a1d419c

File tree

10 files changed

+169
-51
lines changed

10 files changed

+169
-51
lines changed

regression/cbmc-cpp/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
2+
add_test_pl_tests(
3+
"$<TARGET_FILE:cbmc>" -X gcc-only
4+
)
5+
else()
16
add_test_pl_tests(
27
"$<TARGET_FILE:cbmc>"
38
)
9+
endif()

regression/cbmc-cpp/Makefile

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
default: tests.log
22

3+
include ../../src/config.inc
4+
include ../../src/common
5+
6+
ifeq ($(BUILD_ENV_),MSVC)
7+
gcc_only = -X gcc-only
8+
else
9+
gcc_only =
10+
endif
11+
312
test:
4-
@../test.pl -e -p -c ../../../src/cbmc/cbmc
13+
@../test.pl -e -p -c ../../../src/cbmc/cbmc $(gcc_only)
514

615
tests.log: ../test.pl
7-
@../test.pl -e -p -c ../../../src/cbmc/cbmc
16+
@../test.pl -e -p -c ../../../src/cbmc/cbmc $(gcc_only)
817

918
show:
1019
@for dir in *; do \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifdef __GNUC__
2+
const char *__attribute__((weak)) bar();
3+
#endif
4+
5+
int main()
6+
{
7+
#ifdef __GNUC__
8+
return bar() != 0;
9+
#else
10+
return 0
11+
#endif
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE gcc-only
2+
main.cpp
3+
--show-symbol-table
4+
activate-multi-line-match
5+
Symbol\.+: bar\(\)\nPretty name\.+: bar\(\)\nModule\.+: main\nBase name\.+: bar\nMode\.+: cpp\nType\.+: auto \(\) -> const char \*\nValue\.+: \nFlags\.+: weak\n
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
^CONVERSION ERROR$

src/cpp/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ SRC = cpp_constructor.cpp \
1717
cpp_parser.cpp \
1818
cpp_scope.cpp \
1919
cpp_scopes.cpp \
20+
cpp_storage_spec.cpp \
2021
cpp_token_buffer.cpp \
2122
cpp_type2name.cpp \
2223
cpp_typecheck.cpp \

src/cpp/cpp_declarator.h

+10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ class cpp_declaratort:public exprt
4545
return static_cast<const exprt &>(find(ID_value));
4646
}
4747

48+
bool get_is_parameter() const
49+
{
50+
return get_bool(ID_is_parameter);
51+
}
52+
53+
void set_is_parameter(bool is_parameter)
54+
{
55+
set(ID_is_parameter, is_parameter);
56+
}
57+
4858
// initializers for function arguments
4959
exprt &init_args()
5060
{

src/cpp/cpp_declarator_converter.cpp

+42-45
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ symbolt &cpp_declarator_convertert::convert(
5353
final_type=declarator.merge_type(declaration_type);
5454
assert(final_type.is_not_nil());
5555

56+
cpp_storage_spect final_storage_spec = storage_spec;
57+
final_storage_spec |= cpp_storage_spect(final_type);
58+
5659
cpp_template_args_non_tct template_args;
5760

5861
// run resolver on scope
@@ -135,7 +138,7 @@ symbolt &cpp_declarator_convertert::convert(
135138
if(!maybe_symbol && is_friend)
136139
{
137140
symbolt &friend_symbol =
138-
convert_new_symbol(storage_spec, member_spec, declarator);
141+
convert_new_symbol(final_storage_spec, member_spec, declarator);
139142
// mark it as weak so that the full declaration can replace the symbol
140143
friend_symbol.is_weak = true;
141144
return friend_symbol;
@@ -191,7 +194,7 @@ symbolt &cpp_declarator_convertert::convert(
191194
type, declarator.member_initializers());
192195
}
193196

194-
if(!storage_spec.is_extern())
197+
if(!final_storage_spec.is_extern())
195198
symbol.is_extern=false;
196199

197200
// initializer?
@@ -217,10 +220,10 @@ symbolt &cpp_declarator_convertert::convert(
217220
const auto maybe_symbol=
218221
cpp_typecheck.symbol_table.get_writeable(final_identifier);
219222
if(!maybe_symbol)
220-
return convert_new_symbol(storage_spec, member_spec, declarator);
223+
return convert_new_symbol(final_storage_spec, member_spec, declarator);
221224
symbolt &symbol=*maybe_symbol;
222225

223-
if(!storage_spec.is_extern())
226+
if(!final_storage_spec.is_extern())
224227
symbol.is_extern = false;
225228

226229
if(declarator.get_bool(ID_C_template_case))
@@ -449,6 +452,9 @@ symbolt &cpp_declarator_convertert::convert_new_symbol(
449452
symbol.base_name=base_name;
450453
symbol.value=declarator.value();
451454
symbol.location=declarator.name().source_location();
455+
symbol.is_extern = storage_spec.is_extern();
456+
symbol.is_parameter = declarator.get_is_parameter();
457+
symbol.is_weak = storage_spec.is_weak();
452458
symbol.mode=linkage_spec==ID_auto?ID_cpp:linkage_spec;
453459
symbol.module=cpp_typecheck.module;
454460
symbol.type=final_type;
@@ -461,49 +467,40 @@ symbolt &cpp_declarator_convertert::convert_new_symbol(
461467
symbol.value.is_not_nil())
462468
symbol.is_macro=true;
463469

464-
if(member_spec.is_inline())
465-
symbol.type.set(ID_C_inlined, true);
466-
467-
if(!symbol.is_type)
470+
if(is_code && !symbol.is_type)
468471
{
469-
if(is_code)
470-
{
471-
// it is a function
472-
if(storage_spec.is_static())
473-
symbol.is_file_local=true;
474-
}
475-
else
476-
{
477-
// it is a variable
478-
symbol.is_state_var=true;
479-
symbol.is_lvalue = !is_reference(symbol.type) &&
480-
!(symbol.type.get_bool(ID_C_constant) &&
481-
is_number(symbol.type) &&
482-
symbol.value.id() == ID_constant);
483-
484-
if(cpp_typecheck.cpp_scopes.current_scope().is_global_scope())
485-
{
486-
symbol.is_static_lifetime=true;
472+
// it is a function
473+
symbol.is_static_lifetime = false;
474+
symbol.is_thread_local = false;
487475

488-
if(storage_spec.is_extern())
489-
symbol.is_extern=true;
490-
}
491-
else
492-
{
493-
if(storage_spec.is_static())
494-
{
495-
symbol.is_static_lifetime=true;
496-
symbol.is_file_local=true;
497-
}
498-
else if(storage_spec.is_extern())
499-
{
500-
cpp_typecheck.error().source_location=storage_spec.location();
501-
cpp_typecheck.error() << "external storage not permitted here"
502-
<< messaget::eom;
503-
throw 0;
504-
}
505-
}
506-
}
476+
symbol.is_file_local = storage_spec.is_static();
477+
478+
if(member_spec.is_inline())
479+
symbol.type.set(ID_C_inlined, true);
480+
}
481+
else
482+
{
483+
symbol.is_lvalue =
484+
!is_reference(symbol.type) &&
485+
!(symbol.type.get_bool(ID_C_constant) && is_number(symbol.type) &&
486+
symbol.value.id() == ID_constant);
487+
488+
symbol.is_static_lifetime =
489+
!symbol.is_macro && !symbol.is_type &&
490+
(cpp_typecheck.cpp_scopes.current_scope().is_global_scope() ||
491+
storage_spec.is_static());
492+
493+
symbol.is_thread_local =
494+
(!symbol.is_static_lifetime && !storage_spec.is_extern()) ||
495+
storage_spec.is_thread_local();
496+
497+
symbol.is_file_local =
498+
symbol.is_macro ||
499+
(!cpp_typecheck.cpp_scopes.current_scope().is_global_scope() &&
500+
!storage_spec.is_extern()) ||
501+
(cpp_typecheck.cpp_scopes.current_scope().is_global_scope() &&
502+
storage_spec.is_static()) ||
503+
symbol.is_parameter;
507504
}
508505

509506
if(symbol.is_static_lifetime)

src/cpp/cpp_storage_spec.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#include "cpp_storage_spec.h"
10+
11+
void cpp_storage_spect::read(const typet &type)
12+
{
13+
if(type.id() == ID_merged_type || type.id() == ID_function_type)
14+
{
15+
forall_subtypes(it, type)
16+
read(*it);
17+
}
18+
else if(type.id() == ID_static)
19+
set_static();
20+
else if(type.id() == ID_extern)
21+
set_extern();
22+
else if(type.id() == ID_auto)
23+
set_auto();
24+
else if(type.id() == ID_register)
25+
set_register();
26+
else if(type.id() == ID_mutable)
27+
set_mutable();
28+
else if(type.id() == ID_thread_local)
29+
set_thread_local();
30+
else if(type.id() == ID_asm)
31+
set_asm();
32+
else if(type.id() == ID_weak)
33+
set_weak();
34+
}

src/cpp/cpp_storage_spec.h

+41-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Author: Daniel Kroening, [email protected]
1010
#ifndef CPROVER_CPP_CPP_STORAGE_SPEC_H
1111
#define CPROVER_CPP_CPP_STORAGE_SPEC_H
1212

13-
#include <util/source_location.h>
13+
#include <util/type.h>
1414

1515
class cpp_storage_spect:public irept
1616
{
@@ -19,6 +19,11 @@ class cpp_storage_spect:public irept
1919
{
2020
}
2121

22+
explicit cpp_storage_spect(const typet &type)
23+
{
24+
read(type);
25+
}
26+
2227
source_locationt &location()
2328
{
2429
return static_cast<source_locationt &>(add(ID_C_source_location));
@@ -36,6 +41,10 @@ class cpp_storage_spect:public irept
3641
bool is_mutable() const { return get_bool(ID_mutable); }
3742
bool is_thread_local() const { return get_bool(ID_thread_local); }
3843
bool is_asm() const { return get_bool(ID_asm); }
44+
bool is_weak() const
45+
{
46+
return get_bool(ID_weak);
47+
}
3948

4049
void set_static() { set(ID_static, true); }
4150
void set_extern() { set(ID_extern, true); }
@@ -44,13 +53,41 @@ class cpp_storage_spect:public irept
4453
void set_mutable() { set(ID_mutable, true); }
4554
void set_thread_local() { set(ID_thread_local, true); }
4655
void set_asm() { set(ID_asm, true); }
56+
void set_weak()
57+
{
58+
set(ID_weak, true);
59+
}
4760

4861
bool is_empty() const
4962
{
50-
return !is_static() && !is_extern() && !is_auto() &&
51-
!is_register() && !is_mutable() && !is_thread_local() &&
52-
!is_asm();
63+
return !is_static() && !is_extern() && !is_auto() && !is_register() &&
64+
!is_mutable() && !is_thread_local() && !is_asm() && !is_weak();
65+
}
66+
67+
cpp_storage_spect &operator|=(const cpp_storage_spect &other)
68+
{
69+
if(other.is_static())
70+
set_static();
71+
if(other.is_extern())
72+
set_extern();
73+
if(other.is_auto())
74+
set_auto();
75+
if(other.is_register())
76+
set_register();
77+
if(other.is_mutable())
78+
set_mutable();
79+
if(other.is_thread_local())
80+
set_thread_local();
81+
if(other.is_asm())
82+
set_asm();
83+
if(other.is_weak())
84+
set_weak();
85+
86+
return *this;
5387
}
88+
89+
private:
90+
void read(const typet &type);
5491
};
5592

5693
#endif // CPROVER_CPP_CPP_STORAGE_SPEC_H

src/cpp/parse.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -4127,6 +4127,8 @@ bool Parser::rArgDeclaration(cpp_declarationt &declaration)
41274127
if(!rDeclarator(arg_declarator, kArgDeclarator, true, false))
41284128
return false;
41294129

4130+
arg_declarator.set_is_parameter(true);
4131+
41304132
declaration.declarators().push_back(arg_declarator);
41314133

41324134
int t=lex.LookAhead(0);

0 commit comments

Comments
 (0)