Skip to content

C++ front-end fixes #8275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: develop
Choose a base branch
from
16 changes: 16 additions & 0 deletions regression/cbmc-cpp/Constructor7/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <cassert>

int main(int argc, char * argv[])
{
struct S {
S() : x(42)
{
}

int x;
};
S s = S{};

__CPROVER_assert(s.x == 42, "");
assert(s.x == 42);
}
8 changes: 8 additions & 0 deletions regression/cbmc-cpp/Constructor7/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.cpp

^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
^warning: ignoring
24 changes: 24 additions & 0 deletions regression/cpp/brace_initializer1/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
struct __invoke_memfun_ref {};
constexpr bool __call_is_nt(__invoke_memfun_ref)
{
return false;
}

template<typename _Result>
struct __call_is_nothrow
{
constexpr static bool is_nt =
__call_is_nt(typename _Result::__invoke_type{});
};

int main(int argc, char * argv[])
{
struct S {
S() : x(42)
{
}

int x;
};
S s = S{};
}
8 changes: 8 additions & 0 deletions regression/cpp/brace_initializer1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.cpp
-std=c++11
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
^CONVERSION ERROR$
12 changes: 12 additions & 0 deletions regression/cpp/constexpr1/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ constexpr int some_other_value =

static_assert(some_other_value == 2, "some_other_value == 2");

constexpr int some_function2(int a)
{
int b;
a = a + 1;
b = a;
return b + 1;
}

constexpr int some_other_value2 = some_function2(1);

static_assert(some_other_value2 == 3, "some_other_value == 2");

int main()
{
}
2 changes: 1 addition & 1 deletion regression/cpp/constexpr1/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
KNOWNBUG
CORE
main.cpp
-std=c++11
^EXIT=0$
Expand Down
2 changes: 1 addition & 1 deletion regression/cpp/type_traits_essentials1/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
KNOWNBUG
CORE
main.cpp
-std=c++11
^EXIT=0$
Expand Down
4 changes: 4 additions & 0 deletions src/ansi-c/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ int yyansi_cerror(const std::string &error);
%token TOK_MSC_IF_EXISTS "__if_exists"
%token TOK_MSC_IF_NOT_EXISTS "__if_not_exists"
%token TOK_UNDERLYING_TYPE "__underlying_type"
%token TOK_DYNAMIC_CAST "dynamic_cast"
%token TOK_STATIC_CAST "static_cast"
%token TOK_REINTERPRET_CAST "reinterpret_cast"
%token TOK_CONST_CAST "const_cast"

/*** priority, associativity, etc. definitions **************************/

Expand Down
9 changes: 7 additions & 2 deletions src/ansi-c/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,11 @@ __decltype { if(PARSER.cpp98 &&
return make_identifier();
}

"dynamic_cast" { return cpp98_keyword(TOK_DYNAMIC_CAST); }
"static_cast" { return cpp98_keyword(TOK_STATIC_CAST); }
"reinterpret_cast" { return cpp98_keyword(TOK_REINTERPRET_CAST); }
"const_cast" { return cpp98_keyword(TOK_CONST_CAST); }

{CPROVER_PREFIX}"atomic" { loc(); return TOK_CPROVER_ATOMIC; }
{CPROVER_PREFIX}"forall" { loc(); return TOK_FORALL; }
{CPROVER_PREFIX}"exists" { loc(); return TOK_EXISTS; }
Expand Down Expand Up @@ -1431,7 +1436,7 @@ __decltype { if(PARSER.cpp98 &&

/* This is a C11 keyword */

"_Alignof" { if(!PARSER.cpp98 &&
"_Alignof" { if((!PARSER.cpp98 || PARSER.cpp11) &&
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
PARSER.mode==configt::ansi_ct::flavourt::CLANG ||
PARSER.mode==configt::ansi_ct::flavourt::ARM ||
Expand All @@ -1453,7 +1458,7 @@ __decltype { if(PARSER.cpp98 &&
"_Atomic"{ws}"(" { // put back all but _Atomic
yyless(7);

if(!PARSER.cpp98 &&
if((!PARSER.cpp98 || PARSER.cpp11) &&
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
PARSER.mode==configt::ansi_ct::flavourt::CLANG ||
PARSER.mode==configt::ansi_ct::flavourt::ARM))
Expand Down
5 changes: 4 additions & 1 deletion src/cbmc/cbmc_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,11 +542,14 @@ int cbmc_parse_optionst::doit()
register_languages();

// configure gcc, if required
if(config.ansi_c.preprocessor == configt::ansi_ct::preprocessort::GCC)
if(config.ansi_c.preprocessor == configt::ansi_ct::preprocessort::GCC ||
config.ansi_c.preprocessor == configt::ansi_ct::preprocessort::CLANG)
{
gcc_versiont gcc_version;
gcc_version.get("gcc");
configure_gcc(gcc_version);
config.ansi_c.c_standard = gcc_version.default_c_standard;
config.cpp.cpp_standard = gcc_version.default_cxx_standard;
}

if(cmdline.isset("test-preprocessor"))
Expand Down
2 changes: 0 additions & 2 deletions src/cpp/cpp_convert_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ void cpp_convert_typet::read_rec(const typet &type)
++char16_t_count;
else if(type.id()==ID_char32_t)
++char32_t_count;
else if(type.id()==ID_constexpr)
c_qualifiers.is_constant = true;
else if(type.id()==ID_function_type)
{
read_function_type(type);
Expand Down
5 changes: 4 additions & 1 deletion src/cpp/cpp_declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ class cpp_declarationt:public exprt

bool is_class_template() const
{
const typet * t = &type();
while(t->id() == ID_merged_type)
t = &to_type_with_subtypes(*t).subtypes().back();
return is_template() &&
type().id()==ID_struct &&
t->id()==ID_struct &&
declarators().empty();
}

Expand Down
10 changes: 10 additions & 0 deletions src/cpp/cpp_declarator.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ class cpp_declaratort:public exprt
set(ID_is_parameter, is_parameter);
}

bool get_has_ellipsis() const
{
return get_bool(ID_ellipsis);
}

void set_has_ellipsis()
{
set(ID_ellipsis, true);
}

// initializers for function arguments
exprt &init_args()
{
Expand Down
17 changes: 11 additions & 6 deletions src/cpp/cpp_declarator_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ symbolt &cpp_declarator_convertert::convert_new_symbol(
symbol.is_weak = storage_spec.is_weak();
symbol.module=cpp_typecheck.module;
symbol.is_type=is_typedef;
symbol.is_macro=is_typedef && !is_template_parameter;
symbol.is_macro =
(is_typedef && !is_template_parameter) || storage_spec.is_constexpr();
symbol.pretty_name=pretty_name;

if(is_code && !symbol.is_type)
Expand Down Expand Up @@ -493,7 +494,7 @@ symbolt &cpp_declarator_convertert::convert_new_symbol(
storage_spec.is_thread_local();

symbol.is_file_local =
symbol.is_macro ||
(symbol.is_macro && !storage_spec.is_constexpr()) ||
(!cpp_typecheck.cpp_scopes.current_scope().is_global_scope() &&
!storage_spec.is_extern()) ||
(cpp_typecheck.cpp_scopes.current_scope().is_global_scope() &&
Expand Down Expand Up @@ -553,10 +554,14 @@ symbolt &cpp_declarator_convertert::convert_new_symbol(
// do the value
if(!new_symbol->is_type)
{
if(is_code && declarator.type().id()!=ID_template)
cpp_typecheck.add_method_body(new_symbol);

if(!is_code)
if(is_code)
{
if(new_symbol->is_macro)
cpp_typecheck.convert_function(*new_symbol);
else if(declarator.type().id() != ID_template)
cpp_typecheck.add_method_body(new_symbol);
}
else
cpp_typecheck.convert_initializer(*new_symbol);
}

Expand Down
4 changes: 4 additions & 0 deletions src/cpp/cpp_is_pod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ bool cpp_typecheckt::cpp_is_pod(const typet &type) const
{
return cpp_is_pod(to_array_type(type).element_type());
}
else if(type.id()==ID_vector)
{
return cpp_is_pod(to_vector_type(type).element_type());
}
else if(type.id()==ID_pointer)
{
if(is_reference(type)) // references are not PODs
Expand Down
2 changes: 2 additions & 0 deletions src/cpp/cpp_storage_spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ void cpp_storage_spect::read(const typet &type)
set_asm();
else if(type.id() == ID_weak)
set_weak();
else if(type.id() == ID_constexpr)
set_constexpr();
}
13 changes: 12 additions & 1 deletion src/cpp/cpp_storage_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class cpp_storage_spect:public irept
{
return get_bool(ID_weak);
}
bool is_constexpr() const
{
return get_bool(ID_constexpr);
}

void set_static() { set(ID_static, true); }
void set_extern() { set(ID_extern, true); }
Expand All @@ -59,11 +63,16 @@ class cpp_storage_spect:public irept
{
set(ID_weak, true);
}
void set_constexpr()
{
set(ID_constexpr, true);
}

bool is_empty() const
{
return !is_static() && !is_extern() && !is_auto() && !is_register() &&
!is_mutable() && !is_thread_local() && !is_asm() && !is_weak();
!is_mutable() && !is_thread_local() && !is_asm() && !is_weak() &&
!is_constexpr();
}

cpp_storage_spect &operator|=(const cpp_storage_spect &other)
Expand All @@ -84,6 +93,8 @@ class cpp_storage_spect:public irept
set_asm();
if(other.is_weak())
set_weak();
if(other.is_constexpr())
set_constexpr();

return *this;
}
Expand Down
5 changes: 5 additions & 0 deletions src/cpp/cpp_token_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class cpp_token_buffert
void Restore(post pos);
void Replace(const cpp_tokent &token);
void Insert(const cpp_tokent &token);
const cpp_tokent &peek()
{
PRECONDITION(current_pos <= token_vector.size());
return *token_vector[current_pos];
}

void clear()
{
Expand Down
Loading