Skip to content

Commit 6aebbd0

Browse files
committed
C++11 auto type specifier
1 parent c80b932 commit 6aebbd0

12 files changed

+67
-6
lines changed

regression/cpp/auto1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.cpp
33
-std=c++11
44
^EXIT=0$

regression/cpp/auto3/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ int main()
22
{
33
// should yield a parse error unless in C++11 (or later) mode
44
auto x = 42;
5+
const auto y = 42;
6+
const auto &z = y;
57
}

regression/cpp/auto3/test11.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.cpp
3+
-std=c++11
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

src/cpp/cpp_convert_type.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,19 @@ void cpp_convert_plain_type(typet &type)
591591
cpp_convert_type.write(type);
592592
}
593593
}
594+
595+
void cpp_convert_auto(typet &dest, const typet &src)
596+
{
597+
if(dest.id() != ID_merged_type && dest.has_subtype())
598+
{
599+
cpp_convert_auto(dest.subtype(), src);
600+
return;
601+
}
602+
603+
cpp_convert_typet cpp_convert_type(dest);
604+
for(auto &t : cpp_convert_type.other)
605+
if(t.id() == ID_auto)
606+
t = src;
607+
608+
cpp_convert_type.write(dest);
609+
}

src/cpp/cpp_convert_type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ Author: Daniel Kroening, [email protected]
1616

1717
void cpp_convert_plain_type(typet &);
1818

19+
void cpp_convert_auto(typet &dest, const typet &src);
20+
1921
#endif // CPROVER_CPP_CPP_CONVERT_TYPE_H

src/cpp/cpp_declarator_converter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ symbolt &cpp_declarator_convertert::convert(
6868
scope=&cpp_typecheck.cpp_scopes.current_scope();
6969

7070
// check the declarator-part of the type, in that scope
71-
cpp_typecheck.typecheck_type(final_type);
71+
if(declarator.value().is_nil() || !cpp_typecheck.has_auto(final_type))
72+
cpp_typecheck.typecheck_type(final_type);
7273
}
7374

7475
is_code=is_code_type(final_type);

src/cpp/cpp_typecheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ class cpp_typecheckt:public c_typecheck_baset
395395

396396
static bool has_const(const typet &type);
397397
static bool has_volatile(const typet &type);
398+
static bool has_auto(const typet &type);
398399

399400
void typecheck_member_function(
400401
const irep_idt &compound_identifier,

src/cpp/cpp_typecheck_code.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ void cpp_typecheckt::typecheck_decl(codet &code)
366366

367367
bool is_typedef=declaration.is_typedef();
368368

369-
typecheck_type(type);
369+
if(declaration.declarators().empty() || !has_auto(type))
370+
typecheck_type(type);
371+
370372
assert(type.is_not_nil());
371373

372374
if(declaration.declarators().empty() &&
@@ -407,7 +409,10 @@ void cpp_typecheckt::typecheck_decl(codet &code)
407409
symbol.value.id()!=ID_code)
408410
{
409411
decl_statement.copy_to_operands(symbol.value);
410-
assert(follow(decl_statement.op1().type())==follow(symbol.type));
412+
DATA_INVARIANT(
413+
has_auto(symbol.type) ||
414+
follow(decl_statement.op1().type()) == follow(symbol.type),
415+
"declarator type should match symbol type");
411416
}
412417

413418
new_code.move_to_operands(decl_statement);

src/cpp/cpp_typecheck_compound_type.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ bool cpp_typecheckt::has_volatile(const typet &type)
5757
return false;
5858
}
5959

60+
bool cpp_typecheckt::has_auto(const typet &type)
61+
{
62+
if(type.id() == ID_auto)
63+
return true;
64+
else if(type.id() == ID_merged_type || type.id() == ID_frontend_pointer)
65+
{
66+
forall_subtypes(it, type)
67+
if(has_auto(*it))
68+
return true;
69+
70+
return false;
71+
}
72+
else
73+
return false;
74+
}
75+
6076
cpp_scopet &cpp_typecheckt::tag_scope(
6177
const irep_idt &base_name,
6278
bool has_body,

src/cpp/cpp_typecheck_declaration.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ void cpp_typecheckt::convert_non_template_declaration(
122122
declaration.name_anon_struct_union();
123123

124124
// do the type of the declaration
125-
typecheck_type(declaration_type);
125+
if(declaration.declarators().empty() || !has_auto(declaration_type))
126+
typecheck_type(declaration_type);
126127

127128
// Elaborate any class template instance _unless_ we do a typedef.
128129
// These are only elaborated on usage!

src/cpp/cpp_typecheck_initializer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Author: Daniel Kroening, [email protected]
1616
#include <util/expr_initializer.h>
1717
#include <util/pointer_offset_size.h>
1818

19+
#include "cpp_convert_type.h"
20+
1921
/// Initialize an object with a value
2022
void cpp_typecheckt::convert_initializer(symbolt &symbol)
2123
{
@@ -144,6 +146,12 @@ void cpp_typecheckt::convert_initializer(symbolt &symbol)
144146
if(symbol.type.find(ID_size).is_nil())
145147
symbol.type=symbol.value.type();
146148
}
149+
else if(has_auto(symbol.type))
150+
{
151+
cpp_convert_auto(symbol.type, symbol.value.type());
152+
typecheck_type(symbol.type);
153+
implicit_typecast(symbol.value, symbol.type);
154+
}
147155
else
148156
implicit_typecast(symbol.value, symbol.type);
149157

src/cpp/parse.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,7 @@ bool Parser::optStorageSpec(cpp_storage_spect &storage_spec)
19611961

19621962
if(t==TOK_STATIC ||
19631963
t==TOK_EXTERN ||
1964-
t==TOK_AUTO ||
1964+
(t == TOK_AUTO && !ansi_c_parser.cpp11) ||
19651965
t==TOK_REGISTER ||
19661966
t==TOK_MUTABLE ||
19671967
t==TOK_GCC_ASM ||
@@ -2224,6 +2224,7 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p)
22242224
case TOK_GCC_FLOAT128: type_id=ID_gcc_float128; break;
22252225
case TOK_BOOL: type_id=ID_bool; break;
22262226
case TOK_CPROVER_BOOL: type_id=ID_proper_bool; break;
2227+
case TOK_AUTO: type_id = ID_auto; break;
22272228
default: type_id=irep_idt();
22282229
}
22292230

0 commit comments

Comments
 (0)