File tree 12 files changed +67
-6
lines changed 12 files changed +67
-6
lines changed Original file line number Diff line number Diff line change 1
- KNOWNBUG
1
+ CORE
2
2
main.cpp
3
3
-std=c++11
4
4
^EXIT=0$
Original file line number Diff line number Diff line change @@ -2,4 +2,6 @@ int main()
2
2
{
3
3
// should yield a parse error unless in C++11 (or later) mode
4
4
auto x = 42 ;
5
+ const auto y = 42 ;
6
+ const auto &z = y;
5
7
}
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.cpp
3
+ -std=c++11
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ --
7
+ ^warning: ignoring
8
+ ^CONVERSION ERROR$
Original file line number Diff line number Diff line change @@ -591,3 +591,19 @@ void cpp_convert_plain_type(typet &type)
591
591
cpp_convert_type.write (type);
592
592
}
593
593
}
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
+ }
Original file line number Diff line number Diff line change 16
16
17
17
void cpp_convert_plain_type (typet & );
18
18
19
+ void cpp_convert_auto (typet & dest , const typet & src );
20
+
19
21
#endif // CPROVER_CPP_CPP_CONVERT_TYPE_H
Original file line number Diff line number Diff line change @@ -68,7 +68,8 @@ symbolt &cpp_declarator_convertert::convert(
68
68
scope=&cpp_typecheck.cpp_scopes .current_scope ();
69
69
70
70
// 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);
72
73
}
73
74
74
75
is_code=is_code_type (final_type);
Original file line number Diff line number Diff line change @@ -395,6 +395,7 @@ class cpp_typecheckt:public c_typecheck_baset
395
395
396
396
static bool has_const (const typet &type);
397
397
static bool has_volatile (const typet &type);
398
+ static bool has_auto (const typet &type);
398
399
399
400
void typecheck_member_function (
400
401
const irep_idt &compound_identifier,
Original file line number Diff line number Diff line change @@ -366,7 +366,9 @@ void cpp_typecheckt::typecheck_decl(codet &code)
366
366
367
367
bool is_typedef=declaration.is_typedef ();
368
368
369
- typecheck_type (type);
369
+ if (declaration.declarators ().empty () || !has_auto (type))
370
+ typecheck_type (type);
371
+
370
372
assert (type.is_not_nil ());
371
373
372
374
if (declaration.declarators ().empty () &&
@@ -407,7 +409,10 @@ void cpp_typecheckt::typecheck_decl(codet &code)
407
409
symbol.value .id ()!=ID_code)
408
410
{
409
411
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" );
411
416
}
412
417
413
418
new_code.move_to_operands (decl_statement);
Original file line number Diff line number Diff line change @@ -57,6 +57,22 @@ bool cpp_typecheckt::has_volatile(const typet &type)
57
57
return false ;
58
58
}
59
59
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
+
60
76
cpp_scopet &cpp_typecheckt::tag_scope (
61
77
const irep_idt &base_name,
62
78
bool has_body,
Original file line number Diff line number Diff line change @@ -122,7 +122,8 @@ void cpp_typecheckt::convert_non_template_declaration(
122
122
declaration.name_anon_struct_union ();
123
123
124
124
// 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);
126
127
127
128
// Elaborate any class template instance _unless_ we do a typedef.
128
129
// These are only elaborated on usage!
Original file line number Diff line number Diff line change 16
16
#include < util/expr_initializer.h>
17
17
#include < util/pointer_offset_size.h>
18
18
19
+ #include " cpp_convert_type.h"
20
+
19
21
// / Initialize an object with a value
20
22
void cpp_typecheckt::convert_initializer (symbolt &symbol)
21
23
{
@@ -144,6 +146,12 @@ void cpp_typecheckt::convert_initializer(symbolt &symbol)
144
146
if (symbol.type .find (ID_size).is_nil ())
145
147
symbol.type =symbol.value .type ();
146
148
}
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
+ }
147
155
else
148
156
implicit_typecast (symbol.value , symbol.type );
149
157
Original file line number Diff line number Diff line change @@ -1961,7 +1961,7 @@ bool Parser::optStorageSpec(cpp_storage_spect &storage_spec)
1961
1961
1962
1962
if (t==TOK_STATIC ||
1963
1963
t==TOK_EXTERN ||
1964
- t== TOK_AUTO ||
1964
+ (t == TOK_AUTO && !ansi_c_parser. cpp11 ) ||
1965
1965
t==TOK_REGISTER ||
1966
1966
t==TOK_MUTABLE ||
1967
1967
t==TOK_GCC_ASM ||
@@ -2224,6 +2224,7 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p)
2224
2224
case TOK_GCC_FLOAT128: type_id=ID_gcc_float128; break ;
2225
2225
case TOK_BOOL: type_id=ID_bool; break ;
2226
2226
case TOK_CPROVER_BOOL: type_id=ID_proper_bool; break ;
2227
+ case TOK_AUTO: type_id = ID_auto; break ;
2227
2228
default : type_id=irep_idt ();
2228
2229
}
2229
2230
You can’t perform that action at this time.
0 commit comments