Skip to content
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

[clang-cpp] Add delegating constructors #1754

Merged

Conversation

intrigus-lgtm
Copy link
Collaborator

THIS DOES NOT CURRENTLY WORK

I tried to support delegating constructors, but the test does not work so I probably did something wrong.
In theory it should be enough to "just" add a call to the constructor we are delegating to, but I didn't get this to work.
Some pointers would be appreciated.

TranslationUnitDecl 0x561987f16898 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x561987f17198 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x561987f16e30 '__int128'
|-TypedefDecl 0x561987f17208 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x561987f16e50 'unsigned __int128'
|-TypedefDecl 0x561987f17590 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
| `-RecordType 0x561987f172f0 '__NSConstantString_tag'
|   `-CXXRecord 0x561987f17260 '__NSConstantString_tag'
|-TypedefDecl 0x561987f17638 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x561987f175f0 'char *'
|   `-BuiltinType 0x561987f16930 'char'
|-TypedefDecl 0x561987f5a450 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
| `-ConstantArrayType 0x561987f5a3f0 '__va_list_tag [1]' 1 
|   `-RecordType 0x561987f17720 '__va_list_tag'
|     `-CXXRecord 0x561987f17690 '__va_list_tag'
|-LinkageSpecDecl 0x561987f5a550 <<built-in>:1:1, esbmc_intrinsics.h:88:5> <built-in>:1:8 C
| |-FunctionDecl 0x561987f5a680 <esbmc_intrinsics.h:1:1, col:25> col:6 __ESBMC_assume 'void (bool)'
| | `-ParmVarDecl 0x561987f5a5b0 <col:21> col:25 'bool'
| |-FunctionDecl 0x561987f5a8e0 <line:2:1, col:39> col:6 __ESBMC_assert 'void (bool, const char *)'
| | |-ParmVarDecl 0x561987f5a780 <col:21> col:25 'bool'
| | `-ParmVarDecl 0x561987f5a800 <col:27, col:38> col:39 'const char *'
| |-FunctionDecl 0x561987f5ab30 <line:3:1, col:52> col:6 __ESBMC_same_object 'bool (const void *, const void *)'
| | |-ParmVarDecl 0x561987f5a9d8 <col:26, col:37> col:38 'const void *'
| | `-ParmVarDecl 0x561987f5aa58 <col:40, col:51> col:52 'const void *'
| |-FunctionDecl 0x561987f5ac30 <line:4:1, col:20> col:6 __ESBMC_yield 'void ()'
| |-FunctionDecl 0x561987f5acf0 <line:5:1, col:27> col:6 __ESBMC_atomic_begin 'void ()'
| |-FunctionDecl 0x561987f5adb0 <line:6:1, col:25> col:6 __ESBMC_atomic_end 'void ()'
| |-FunctionDecl 0x561987f5af30 <line:9:1, col:31> col:6 __ESBMC_init_object 'void (void *)'
| | `-ParmVarDecl 0x561987f5ae68 <col:26, col:30> col:31 'void *'
| |-FunctionDecl 0x561987f5b0c8 <<built-in>:125:26, esbmc_intrinsics.h:12:53> col:18 __ESBMC_POINTER_OBJECT 'unsigned long (const void *)'
| | `-ParmVarDecl 0x561987f5aff0 <col:41, col:52> col:53 'const void *'
| |-FunctionDecl 0x561987f5b258 <<built-in>:102:26, esbmc_intrinsics.h:13:53> col:18 __ESBMC_POINTER_OFFSET 'long (const void *)'
| | `-ParmVarDecl 0x561987f5b188 <col:41, col:52> col:53 'const void *'
| |-VarDecl 0x561987f83740 <line:16:1, line:17:21> col:6 __ESBMC_alloc 'bool [1]'
| | `-AnnotateAttr 0x561987f837a8 <line:16:16, col:43> "__ESBMC_inf_size"
| |-VarDecl 0x561987f838a0 <line:19:1, line:20:26> col:6 __ESBMC_is_dynamic 'bool [1]'
| | `-AnnotateAttr 0x561987f83908 <line:19:16, col:43> "__ESBMC_inf_size"
| |-VarDecl 0x561987f83a48 <line:22:1, line:23:35> col:15 __ESBMC_alloc_size 'unsigned long [1]'
| | `-AnnotateAttr 0x561987f83ab0 <line:22:16, col:43> "__ESBMC_inf_size"
| |-FunctionDecl 0x561987f83bd0 <<built-in>:110:23, esbmc_intrinsics.h:26:51> col:15 __ESBMC_get_object_size 'unsigned long (const void *)'
| | `-ParmVarDecl 0x561987f83b38 <col:39, col:50> col:51 'const void *'
| |-FunctionDecl 0x561987f83cd0 <line:28:1, col:31> col:6 __ESBMC_is_little_endian 'bool ()'
| |-VarDecl 0x561987f83d88 <line:30:1, col:29> col:5 __ESBMC_rounding_mode 'int' cinit
| | `-IntegerLiteral 0x561987f83df0 <col:29> 'int' 0
| |-FunctionDecl 0x561987f84018 <line:32:1, col:47> col:7 __ESBMC_memset 'void *(void *, int, unsigned int)'
| | |-ParmVarDecl 0x561987f83e28 <col:22, col:27> col:28 'void *'
| | |-ParmVarDecl 0x561987f83ea8 <col:30> col:33 'int'
| | `-ParmVarDecl 0x561987f83f28 <col:35, col:44> col:47 'unsigned int'
| |-FunctionDecl 0x561987f84240 <line:36:1, col:56> col:6 __ESBMC_bitcast 'void (void *, void *)'
| | |-ParmVarDecl 0x561987f840e8 <col:22, col:27> col:38 'void *'
| | `-ParmVarDecl 0x561987f84168 <col:40, col:45> col:56 'void *'
| |-FunctionDecl 0x561987f84310 <line:40:1, col:33> col:6 __ESBMC_memory_leak_checks 'void ()'
| |-FunctionDecl 0x561987f84448 <line:45:1, col:42> col:6 __ESBMC_pthread_start_main_hook 'void ()'
| |-FunctionDecl 0x561987f85610 <line:46:1, col:40> col:6 __ESBMC_pthread_end_main_hook 'void ()'
| |-FunctionDecl 0x561987f85748 <line:50:1, col:33> col:6 __ESBMC_atexit_handler 'void ()'
| |-FunctionDecl 0x561987f85848 <line:53:1, col:16> col:5 nondet_int 'int ()'
| |-FunctionDecl 0x561987f85948 <line:54:1, col:26> col:14 nondet_uint 'unsigned int ()'
| |-FunctionDecl 0x561987f85a48 <line:55:1, col:18> col:6 nondet_long 'long ()'
| |-FunctionDecl 0x561987f85b48 <line:56:1, col:28> col:15 nondet_ulong 'unsigned long ()'
| |-FunctionDecl 0x561987f85c48 <line:57:1, col:20> col:7 nondet_short 'short ()'
| |-FunctionDecl 0x561987f85d48 <line:58:1, col:30> col:16 nondet_ushort 'unsigned short ()'
| |-FunctionDecl 0x561987f85e40 <line:59:1, col:18> col:6 nondet_char 'char ()'
| |-FunctionDecl 0x561987f85f38 <line:60:1, col:28> col:15 nondet_uchar 'unsigned char ()'
| |-FunctionDecl 0x561987f86038 <line:61:1, col:26> col:13 nondet_schar 'signed char ()'
| |-FunctionDecl 0x561987f860f8 <line:62:1, col:18> col:6 nondet_bool 'bool ()'
| |-FunctionDecl 0x561987f861f8 <line:63:1, col:20> col:7 nondet_float 'float ()'
| |-FunctionDecl 0x561987f862f8 <line:64:1, col:22> col:8 nondet_double 'double ()'
| |-FunctionDecl 0x561987f863c0 <line:67:1, col:27> col:5 __VERIFIER_nondet_int 'int ()'
| |-FunctionDecl 0x561987f86488 <line:68:1, col:37> col:14 __VERIFIER_nondet_uint 'unsigned int ()'
| |-FunctionDecl 0x561987f86550 <line:69:1, col:29> col:6 __VERIFIER_nondet_long 'long ()'
| |-FunctionDecl 0x561987f86648 <line:70:1, col:39> col:15 __VERIFIER_nondet_ulong 'unsigned long ()'
| |-FunctionDecl 0x561987f86710 <line:71:1, col:31> col:7 __VERIFIER_nondet_short 'short ()'
| |-FunctionDecl 0x561987f867d8 <line:72:1, col:41> col:16 __VERIFIER_nondet_ushort 'unsigned short ()'
| |-FunctionDecl 0x561987f86898 <line:73:1, col:29> col:6 __VERIFIER_nondet_char 'char ()'
| |-FunctionDecl 0x561987f86960 <line:74:1, col:39> col:15 __VERIFIER_nondet_uchar 'unsigned char ()'
| |-FunctionDecl 0x561987f86a28 <line:75:1, col:37> col:13 __VERIFIER_nondet_schar 'signed char ()'
| |-FunctionDecl 0x561987f86ae8 <line:76:1, col:29> col:6 __VERIFIER_nondet_bool 'bool ()'
| |-FunctionDecl 0x561987f86bb0 <line:77:1, col:31> col:7 __VERIFIER_nondet_float 'float ()'
| |-FunctionDecl 0x561987f86c78 <line:78:1, col:33> col:8 __VERIFIER_nondet_double 'double ()'
| |-FunctionDecl 0x561987f86d38 <line:80:1, col:23> col:6 __VERIFIER_error 'void ()'
| |-FunctionDecl 0x561987f86ec0 <line:81:1, col:27> col:6 __VERIFIER_assume 'void (int)'
| | `-ParmVarDecl 0x561987f86df0 <col:24> col:27 'int'
| |-FunctionDecl 0x561987f86f88 <line:82:1, col:30> col:6 __VERIFIER_atomic_begin 'void ()'
| |-FunctionDecl 0x561987f87048 <line:83:1, col:28> col:6 __VERIFIER_atomic_end 'void ()'
| `-FunctionDecl 0x561987f87108 <line:87:1, col:26> col:6 __ESBMC_unreachable 'void ()'
|-LinkageSpecDecl 0x561987f871c8 </usr/include/x86_64-linux-gnu/sys/cdefs.h:133:24, line:134:22> line:133:31 C
| |-FunctionDecl 0x561987fa7d20 </usr/include/assert.h:69:1, line:71:43> line:69:13 used __assert_fail 'void (const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)' extern
| | |-ParmVarDecl 0x561987f87230 <col:28, col:40> col:40 __assertion 'const char *'
| | |-ParmVarDecl 0x561987f872b0 <col:53, col:65> col:65 __file 'const char *'
| | |-ParmVarDecl 0x561987f87330 <line:70:7, col:20> col:20 __line 'unsigned int'
| | `-ParmVarDecl 0x561987f873b0 <col:28, col:40> col:40 __function 'const char *'
| |-FunctionDecl 0x561987fa81b0 <line:74:1, line:76:43> line:74:13 __assert_perror_fail 'void (int, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)' extern
| | |-ParmVarDecl 0x561987fa7df8 <col:35, col:39> col:39 __errnum 'int'
| | |-ParmVarDecl 0x561987fa7e78 <col:49, col:61> col:61 __file 'const char *'
| | |-ParmVarDecl 0x561987fa7ef8 <line:75:7, col:20> col:20 __line 'unsigned int'
| | `-ParmVarDecl 0x561987fa7f78 <col:28, col:40> col:40 __function 'const char *'
| `-FunctionDecl 0x561987fa85a0 <line:81:1, line:82:43> line:81:13 __assert 'void (const char *, const char *, int) __attribute__((noreturn)) noexcept(true)' extern
|   |-ParmVarDecl 0x561987fa8288 <col:23, col:35> col:35 __assertion 'const char *'
|   |-ParmVarDecl 0x561987fa8308 <col:48, col:60> col:60 __file 'const char *'
|   `-ParmVarDecl 0x561987fa8388 <col:68, col:72> col:72 __line 'int'
|-CXXRecordDecl 0x561987fa8658 </home/sg/dev/esbmc/regression/esbmc-cpp11/constructors/DelegatingConstructor/main.cpp:3:1, line:12:1> line:3:8 referenced struct a definition
| |-DefinitionData pass_in_registers standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
| | |-DefaultConstructor exists non_trivial user_provided
| | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
| | |-MoveConstructor exists simple trivial
| | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
| | |-MoveAssignment exists simple trivial needs_implicit
| | `-Destructor simple irrelevant trivial
| |-CXXRecordDecl 0x561987fa8780 <col:1, col:8> col:8 implicit referenced struct a
| |-FieldDecl 0x561987fa8828 <line:5:3, col:10> col:10 referenced d 'double'
| |-CXXConstructorDecl 0x561987fa89b0 <line:6:3, line:8:3> line:6:3 used a 'void (double)'
| | |-ParmVarDecl 0x561987fa8890 <col:5, col:12> col:12 used double_ 'double'
| | |-CXXCtorInitializer Field 0x561987fa8828 'd' 'double'
| | | `-ImplicitCastExpr 0x561987fa8b80 <col:25> 'double' <LValueToRValue>
| | |   `-DeclRefExpr 0x561987fa8b40 <col:25> 'double' lvalue ParmVar 0x561987fa8890 'double_' 'double'
| | `-CompoundStmt 0x561987fa8bc8 <line:7:3, line:8:3>
| |-CXXConstructorDecl 0x561987fa8a80 <line:9:3, line:11:3> line:9:3 used a 'void ()'
| | |-CXXCtorInitializer 'a'
| | | `-CXXConstructExpr 0x561987faebd0 <col:9, col:14> 'a' 'void (double)'
| | |   `-FloatingLiteral 0x561987fa8bd8 <col:11> 'double' 2.000000e+00
| | `-CompoundStmt 0x561987faed50 <line:10:3, line:11:3>
| |-CXXConstructorDecl 0x561987fa8c60 <line:3:8> col:8 implicit constexpr a 'void (const a &)' inline default trivial noexcept-unevaluated 0x561987fa8c60
| | `-ParmVarDecl 0x561987fae990 <col:8> col:8 'const a &'
| |-CXXConstructorDecl 0x561987faea30 <col:8> col:8 implicit constexpr a 'void (a &&)' inline default trivial noexcept-unevaluated 0x561987faea30
| | `-ParmVarDecl 0x561987faeb60 <col:8> col:8 'a &&'
| `-CXXDestructorDecl 0x561987faec30 <col:8> col:8 implicit referenced ~a 'void () noexcept' inline default trivial
`-FunctionDecl 0x561987faed88 <line:14:1, line:20:1> line:14:5 main 'int ()'
  `-CompoundStmt 0x561987fb1890 <line:15:1, line:20:1>
    |-DeclStmt 0x561987faef48 <line:16:3, col:16>
    | `-VarDecl 0x561987faee70 <col:3, col:15> col:5 used second 'a' callinit
    |   `-CXXConstructExpr 0x561987faef18 <col:5, col:15> 'a' 'void (double)'
    |     `-FloatingLiteral 0x561987faeed8 <col:12> 'double' 5.000000e+00
    |-DeclStmt 0x561987faf000 <line:17:3, col:10>
    | `-VarDecl 0x561987faef70 <col:3, col:5> col:5 used third 'a' callinit
    |   `-CXXConstructExpr 0x561987faefd8 <col:5> 'a' 'void ()'
    |-ParenExpr 0x561987faf5a8 </usr/include/assert.h:93:6, line:95:69> 'void'
    | `-ConditionalOperator 0x561987faf578 <line:93:7, line:95:68> 'void'
    |   |-CXXStaticCastExpr 0x561987faf0d0 <line:93:7, col:31> 'bool' static_cast<_Bool> <NoOp>
    |   | `-BinaryOperator 0x561987faf0a0 </home/sg/dev/esbmc/regression/esbmc-cpp11/constructors/DelegatingConstructor/main.cpp:18:10, col:22> 'bool' '=='
    |   |   |-ImplicitCastExpr 0x561987faf088 <col:10, col:17> 'double' <LValueToRValue>
    |   |   | `-MemberExpr 0x561987faf038 <col:10, col:17> 'double' lvalue .d 0x561987fa8828
    |   |   |   `-DeclRefExpr 0x561987faf018 <col:10> 'a' lvalue Var 0x561987faee70 'second' 'a'
    |   |   `-FloatingLiteral 0x561987faf068 <col:22> 'double' 5.000000e+00
    |   |-CXXFunctionalCastExpr 0x561987faf130 </usr/include/assert.h:94:9, col:16> 'void' functional cast to void <ToVoid>
    |   | `-IntegerLiteral 0x561987faf110 <col:15> 'int' 0
    |   `-CallExpr 0x561987faf4d8 <line:95:9, col:68> 'void'
    |     |-ImplicitCastExpr 0x561987faf4c0 <col:9> 'void (*)(const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)' <FunctionToPointerDecay>
    |     | `-DeclRefExpr 0x561987faf438 <col:9> 'void (const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)' lvalue Function 0x561987fa7d20 '__assert_fail' 'void (const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)'
    |     |-ImplicitCastExpr 0x561987faf518 <<scratch space>:20:1> 'const char *' <ArrayToPointerDecay>
    |     | `-StringLiteral 0x561987faf220 <col:1> 'const char [16]' lvalue "second.d == 5.0"
    |     |-ImplicitCastExpr 0x561987faf530 <line:21:1> 'const char *' <ArrayToPointerDecay>
    |     | `-StringLiteral 0x561987faf2d0 <col:1> 'const char [86]' lvalue "/home/sg/dev/esbmc/regression/esbmc-cpp11/constructors/DelegatingConstructor/main.cpp"
    |     |-ImplicitCastExpr 0x561987faf548 <line:22:1> 'unsigned int' <IntegralCast>
    |     | `-IntegerLiteral 0x561987faf340 <col:1> 'int' 18
    |     `-ImplicitCastExpr 0x561987faf560 </usr/include/assert.h:129:30, col:44> 'const char *' <ArrayToPointerDecay>
    |       `-UnaryOperator 0x561987faf420 <col:30, col:44> 'const char [11]' lvalue prefix '__extension__' cannot overflow
    |         `-PredefinedExpr 0x561987faf408 <col:44> 'const char [11]' lvalue __PRETTY_FUNCTION__
    |           `-StringLiteral 0x561987faf3e0 <col:44> 'const char [11]' lvalue "int main()"
    `-ParenExpr 0x561987fb1870 <line:93:6, line:95:69> 'void'
      `-ConditionalOperator 0x561987fb1840 <line:93:7, line:95:68> 'void'
        |-CXXStaticCastExpr 0x561987faf738 <line:93:7, col:31> 'bool' static_cast<_Bool> <NoOp>
        | `-BinaryOperator 0x561987faf708 </home/sg/dev/esbmc/regression/esbmc-cpp11/constructors/DelegatingConstructor/main.cpp:19:10, col:21> 'bool' '=='
        |   |-ImplicitCastExpr 0x561987faf6f0 <col:10, col:16> 'double' <LValueToRValue>
        |   | `-MemberExpr 0x561987faf6a0 <col:10, col:16> 'double' lvalue .d 0x561987fa8828
        |   |   `-DeclRefExpr 0x561987faf680 <col:10> 'a' lvalue Var 0x561987faef70 'third' 'a'
        |   `-FloatingLiteral 0x561987faf6d0 <col:21> 'double' 2.000000e+00
        |-CXXFunctionalCastExpr 0x561987faf798 </usr/include/assert.h:94:9, col:16> 'void' functional cast to void <ToVoid>
        | `-IntegerLiteral 0x561987faf778 <col:15> 'int' 0
        `-CallExpr 0x561987fb17a0 <line:95:9, col:68> 'void'
          |-ImplicitCastExpr 0x561987fb1788 <col:9> 'void (*)(const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)' <FunctionToPointerDecay>
          | `-DeclRefExpr 0x561987fb1768 <col:9> 'void (const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)' lvalue Function 0x561987fa7d20 '__assert_fail' 'void (const char *, const char *, unsigned int, const char *) __attribute__((noreturn)) noexcept(true)'
          |-ImplicitCastExpr 0x561987fb17e0 <<scratch space>:23:1> 'const char *' <ArrayToPointerDecay>
          | `-StringLiteral 0x561987faf890 <col:1> 'const char [15]' lvalue "third.d == 2.0"
          |-ImplicitCastExpr 0x561987fb17f8 <line:24:1> 'const char *' <ArrayToPointerDecay>
          | `-StringLiteral 0x561987fb1680 <col:1> 'const char [86]' lvalue "/home/sg/dev/esbmc/regression/esbmc-cpp11/constructors/DelegatingConstructor/main.cpp"
          |-ImplicitCastExpr 0x561987fb1810 <line:25:1> 'unsigned int' <IntegralCast>
          | `-IntegerLiteral 0x561987fb16f0 <col:1> 'int' 19
          `-ImplicitCastExpr 0x561987fb1828 </usr/include/assert.h:129:30, col:44> 'const char *' <ArrayToPointerDecay>
            `-UnaryOperator 0x561987fb1750 <col:30, col:44> 'const char [11]' lvalue prefix '__extension__' cannot overflow
              `-PredefinedExpr 0x561987fb1738 <col:44> 'const char [11]' lvalue __PRETTY_FUNCTION__
                `-StringLiteral 0x561987fb1710 <col:44> 'const char [11]' lvalue "int main()"

GOTO Program:

Converting
Generating GOTO Program
GOTO program creation time: 0.338s
GOTO program processing time: 0.001s
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

__ESBMC_pthread_start_main_hook (c:@F@__ESBMC_pthread_start_main_hook):
        // 0 no location
        FUNCTION_CALL:  yield()
        // 1 file pthread_lib.c line 118 column 3 function __ESBMC_pthread_start_main_hook
        ATOMIC_BEGIN
        // 2 file pthread_lib.c line 119 column 3 function __ESBMC_pthread_start_main_hook
        num_total_threads=num_total_threads + 1;
        // 3 file pthread_lib.c line 120 column 3 function __ESBMC_pthread_start_main_hook
        num_threads_running=num_threads_running + 1;
        // 4 file pthread_lib.c line 121 column 3 function __ESBMC_pthread_start_main_hook
        ATOMIC_END
        // 5 file pthread_lib.c line 122 column 1 function __ESBMC_pthread_start_main_hook
        END_FUNCTION // __ESBMC_pthread_start_main_hook
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

__ESBMC_pthread_end_main_hook (c:@F@__ESBMC_pthread_end_main_hook):
        // 6 no location
        FUNCTION_CALL:  yield()
        // 7 file pthread_lib.c line 130 column 3 function __ESBMC_pthread_end_main_hook
        ATOMIC_BEGIN
        // 8 file pthread_lib.c line 131 column 3 function __ESBMC_pthread_end_main_hook
        num_threads_running=num_threads_running - 1;
        // 9 file pthread_lib.c line 132 column 1 function __ESBMC_pthread_end_main_hook
        END_FUNCTION // __ESBMC_pthread_end_main_hook
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

__ESBMC_atexit_handler (c:@F@__ESBMC_atexit_handler):
        // 10 file stdlib.c line 33 column 3 function __ESBMC_atexit_handler
        // Labels: __ESBMC_HIDE
        IF atexits == (struct struct atexit_key *)0 THEN GOTO 2
        // 11 file stdlib.c line 36 column 3 function __ESBMC_atexit_handler
     1: IF !(_Bool)atexits THEN GOTO 2
        // 12 file stdlib.c line 38 column 5 function __ESBMC_atexit_handler
        FUNCTION_CALL:  *atexits->atexit_func()
        // 13 file stdlib.c line 39 column 5 function __ESBMC_atexit_handler
        struct struct atexit_key * tmp;
        // 14 file stdlib.c line 39 column 5 function __ESBMC_atexit_handler
        tmp=atexits->next;
        // 15 file stdlib.c line 40 column 5 function __ESBMC_atexit_handler
        FREE((void *)atexits);
        // 16 file stdlib.c line 41 column 5 function __ESBMC_atexit_handler
        atexits=tmp;
        // 17 file stdlib.c line 42 column 3 function __ESBMC_atexit_handler
        dead tmp;
        // 18 file stdlib.c line 36 column 3 function __ESBMC_atexit_handler
        GOTO 1
        // 19 file stdlib.c line 43 column 1 function __ESBMC_atexit_handler
     2: END_FUNCTION // __ESBMC_atexit_handler
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

a (c:@S@a@F@a#d#):
        // 20 
        this->d=double_;
        // 21 file main.cpp line 8 column 3 function a
        END_FUNCTION // a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

a (c:@S@a@F@a#):
        // 22 file main.cpp line 9 column 9 function a
        a tmp$1;
        // 23 file main.cpp line 9 column 9 function a
        tmp$1=NONDET(struct);
        // 24 
        FUNCTION_CALL:  a(&tmp$1, 2.000000)
        // 25 
        tmp$1;

        // 26 no location
        FUNCTION_CALL:  ~a(&tmp$1)
        // 27 file main.cpp line 11 column 3 function a
        dead tmp$1;
        // 28 file main.cpp line 11 column 3 function a
        END_FUNCTION // a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

main (c:@F@main#):
        // 29 file main.cpp line 16 column 3 function main
        a second;
        // 30 file main.cpp line 16 column 5 function main
        a tmp$1;
        // 31 file main.cpp line 16 column 5 function main
        tmp$1=NONDET(struct);
        // 32 
        FUNCTION_CALL:  a(&tmp$1, 5.000000)
        // 33 file main.cpp line 16 column 3 function main
        second=tmp$1;
        // 34 file main.cpp line 17 column 3 function main
        a third;
        // 35 file main.cpp line 17 column 5 function main
        a tmp$2;
        // 36 file main.cpp line 17 column 5 function main
        tmp$2=NONDET(struct);
        // 37 
        FUNCTION_CALL:  a(&tmp$2)
        // 38 file main.cpp line 17 column 3 function main
        third=tmp$2;
        // 39 file main.cpp line 18 column 3 function main
        ASSERT second.d == 5.000000 // assertion second.d == 5.0
        // 40 file main.cpp line 18 column 3 function main
        IF !(second.d == 5.000000) THEN GOTO 1
        // 41 file main.cpp line 18 column 3 function main
        0;

        // 42 file main.cpp line 19 column 3 function main
     1: ASSERT third.d == 2.000000 // assertion third.d == 2.0
        // 43 file main.cpp line 19 column 3 function main
        IF !(third.d == 2.000000) THEN GOTO 2
        // 44 file main.cpp line 19 column 3 function main
        0;

        // 45 no location
     2: FUNCTION_CALL:  ~a(&third)
        // 46 file main.cpp line 20 column 1 function main
        dead third;
        // 47 no location
        FUNCTION_CALL:  ~a(&tmp$2)
        // 48 file main.cpp line 20 column 1 function main
        dead tmp$2;
        // 49 no location
        FUNCTION_CALL:  ~a(&second)
        // 50 file main.cpp line 20 column 1 function main
        dead second;
        // 51 no location
        FUNCTION_CALL:  ~a(&tmp$1)
        // 52 file main.cpp line 20 column 1 function main
        dead tmp$1;
        // 53 file main.cpp line 20 column 1 function main
        RETURN: NONDET(signed int)
        // 54 file main.cpp line 20 column 1 function main
        END_FUNCTION // main
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

__ESBMC_main (__ESBMC_main):
        // 55 file esbmc_intrinsics.h line 16 column 1
        alloc=ARRAY_OF(0);
        // 56 file esbmc_intrinsics.h line 19 column 1
        is_dynamic=ARRAY_OF(0);
        // 57 file esbmc_intrinsics.h line 22 column 1
        alloc_size={ 0 };
        // 58 file esbmc_intrinsics.h line 30 column 1
        rounding_mode=0;
        // 59 file pthread_lib.c line 49 column 1
        num_threads_running=0;
        // 60 file stdlib.c line 27 column 1
        atexits=0;
        // 61 file pthread_lib.c line 48 column 1
        num_total_threads=0;
        // 62 no location
        FUNCTION_CALL:  pthread_start_main_hook()
        // 63 no location
        FUNCTION_CALL:  main()
        // 64 no location
        FUNCTION_CALL:  atexit_handler()
        // 65 no location
        FUNCTION_CALL:  pthread_end_main_hook()
        // 66 file main.cpp line 20 column 1 function main
        END_FUNCTION // main

SMT constraints

Starting Bounded Model Checking
WARNING: no body for function ~a#
WARNING: no body for function ~a#
WARNING: no body for function ~a#
WARNING: no body for function ~a#
WARNING: no body for function ~a#
Symex completed in: 0.002s (27 assignments)
Slicing time: 0.000s (removed 20 assignments)

Program constraints: 
// 31 file main.cpp line 16 column 5 function main
/* 1 */ main#::$tmp::tmp$1?1!0&0#1 == nondet_symbol(symex::nondet0)

// 20 
/* 2 */ main#::$tmp::tmp$1?1!0&0#2 == (main#::$tmp::tmp$1?1!0&0#1 WITH [d:=5.000000])

// 33 file main.cpp line 16 column 3 function main
/* 3 */ second?1!0&0#1 == main#::$tmp::tmp$1?1!0&0#2

// 36 file main.cpp line 17 column 5 function main
/* 4 */ main#::$tmp::tmp$2?1!0&0#1 == nondet_symbol(symex::nondet1)

// 38 file main.cpp line 17 column 3 function main
/* 5 */ third?1!0&0#1 == main#::$tmp::tmp$2?1!0&0#1

// 39 file main.cpp line 18 column 3 function main (assertion second.d == 5.0)
/* 6 */ (assert)execution_statet::\guard_exec?0!0 => second?1!0&0#1.d == 5.000000

// 42 file main.cpp line 19 column 3 function main (assertion third.d == 2.0)
/* 7 */ (assert)execution_statet::\guard_exec?0!0 => third?1!0&0#1.d == 2.000000


Generated 6 VCC(s), 2 remaining after simplification (7 assignments)
No solver specified; defaulting to z3
Encoding remaining VCC(s) using bit-vector/floating-point arithmetic
Encoding to solver time: 0.000s
Total number of safety properties: 16
Solving with solver Z3 v4.8.12
Runtime decision procedure: 0.002s
(define-fun |c:main.cpp@143@F@main#@third?1!0&0#1| () struct_type_a
  (struct_type_a (fp #b1 #b00000000000 #x0000000000001)))
(define-fun |execution_statet::\\guard_exec?0!0| () Bool
  true)
(define-fun |nondet$symex::nondet1| () struct_type_a
  (struct_type_a (fp #b1 #b00000000000 #x0000000000001)))
(define-fun |c:@F@main#::$tmp::tmp$2?1!0&0#1| () struct_type_a
  (struct_type_a (fp #b1 #b00000000000 #x0000000000001)))
(define-fun |c:main.cpp@126@F@main#@second?1!0&0#1| () struct_type_a
  (struct_type_a (fp #b0 #b10000000001 #x4000000000000)))
(define-fun |c:@F@main#::$tmp::tmp$1?1!0&0#2| () struct_type_a
  (struct_type_a (fp #b0 #b10000000001 #x4000000000000)))
(define-fun |c:@F@main#::$tmp::tmp$1?1!0&0#1| () struct_type_a
  (struct_type_a (_ NaN 11 53)))
(define-fun |nondet$symex::nondet0| () struct_type_a
  (struct_type_a (_ NaN 11 53)))
(define-fun INVALID () struct_type_pointer_struct
  (struct_type_pointer_struct #x0000000000000001 #x0000000000000000))
(define-fun NULL () struct_type_pointer_struct
  (struct_type_pointer_struct #x0000000000000000 #x0000000000000000))
(define-fun __ESBMC_addrspace_arr_1 () (Array (_ BitVec 64) struct_type_addr_space_type)
  ((as const (Array (_ BitVec 64) struct_type_addr_space_type))
  (struct_type_addr_space_type #x0000000000000000 #x0000000000000000)))
(define-fun __ESBMC_addrspace_arr_3 () (Array (_ BitVec 64) struct_type_addr_space_type)
  (store ((as const (Array (_ BitVec 64) struct_type_addr_space_type))
         (struct_type_addr_space_type #x0000000000000000 #x0000000000000000))
       #x0000000000000001
       (struct_type_addr_space_type #x0000000000000001 #xffffffffffffffff)))
(define-fun __ESBMC_addrspace_arr_2 () (Array (_ BitVec 64) struct_type_addr_space_type)
  ((as const (Array (_ BitVec 64) struct_type_addr_space_type))
  (struct_type_addr_space_type #x0000000000000000 #x0000000000000000)))
(define-fun __ESBMC_ptr_addr_range_1 () struct_type_addr_space_type
  (struct_type_addr_space_type #x0000000000000001 #xffffffffffffffff))
(define-fun __ESBMC_ptr_addr_range_0 () struct_type_addr_space_type
  (struct_type_addr_space_type #x0000000000000000 #x0000000000000000))
(define-fun __ESBMC_ptr_obj_end_1 () (_ BitVec 64)
  #xffffffffffffffff)
(define-fun __ESBMC_ptr_obj_start_1 () (_ BitVec 64)
  #x0000000000000001)
(define-fun __ESBMC_ptr_obj_end_0 () (_ BitVec 64)
  #x0000000000000000)
(define-fun __ESBMC_ptr_obj_start_0 () (_ BitVec 64)
  #x0000000000000000)
Building error trace
Counterexample
[Counterexample]


State 1 file main.cpp line 16 column 3 function main thread 0
----------------------------------------------------
  second = { .d=tmp$1.d }

State 2 file main.cpp line 17 column 3 function main thread 0
----------------------------------------------------
  third = { .d=tmp$2.d }

State 4 file main.cpp line 19 column 3 function main thread 0
----------------------------------------------------
Violated property:
  file main.cpp line 19 column 3 function main
  assertion third.d == 2.0
  third.d == 2.000000


VERIFICATION FAILED

@XLiZHI
Copy link
Collaborator

XLiZHI commented Mar 19, 2024

I believe you forgot the lvalue, in this goto functions you can see that tmp$1 is not assigned to any value.

a (c:@S@a@F@a#):
        // 22 file main.cpp line 9 column 9 function a
        a tmp$1;
        // 23 file main.cpp line 9 column 9 function a
        tmp$1=NONDET(struct);
        // 24 
        FUNCTION_CALL:  a(&tmp$1, 2.000000)
        // 25 
        tmp$1;                       <------here

        // 26 no location
        FUNCTION_CALL:  ~a(&tmp$1)
        // 27 file main.cpp line 11 column 3 function a
        dead tmp$1;
        // 28 file main.cpp line 11 column 3 function a
        END_FUNCTION // a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can compare it with the right one:

        a third;
        // 35 file main.cpp line 17 column 5 function main
        a tmp$2;
        // 36 file main.cpp line 17 column 5 function main
        tmp$2=NONDET(struct);
        // 37 
        FUNCTION_CALL:  a(&tmp$2)
        // 38 file main.cpp line 17 column 3 function main
        third=tmp$2;

else if (init->isDelegatingInitializer())
{
if (get_expr(*init->getInit(), initializer))
return true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, it might be missing the assign exprt.

like this:

initializer = side_effect_exprt("assign", lhs.type());
initializer.copy_to_operands(lhs, rhs);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what would be the lhs?
Using this would feel a bit weird.

@intrigus-lgtm intrigus-lgtm force-pushed the add-delegating-constructors branch from 1c8fd89 to 59f94d5 Compare March 19, 2024 21:27
@intrigus-lgtm
Copy link
Collaborator Author

I implemented this by basically copying the code that handles calls to the base from derived ctors and modified it for delegating ctors: https://github.com/esbmc/esbmc/pull/1754/files#diff-784347884400427356b283749ef36cc6e458d4d4df4f8e3a2a4007244a637b1eL976-L981

Copy link
Collaborator

@fbrausse fbrausse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @intrigus-lgtm. Though I'm a bit concerned about the increasing complexity for constructors and member initialization. Might need to start a design phase to investigate a less intertwined solution.

@intrigus-lgtm
Copy link
Collaborator Author

@fbrausse it should be possible to more or less merge the base-derived stuff and delegating stuff.
Would have to rename stuff a bit, but the cases are pretty much identical.
In fact, when testing I simply used the code for the base-derived stuff as-is and just made it also apply to delegating constructors.

I can do this in this PR if you want.

@intrigus-lgtm intrigus-lgtm changed the title [WIP] Add delegating constructors [clang-cpp] Add delegating constructors Mar 19, 2024
@fbrausse
Copy link
Collaborator

@fbrausse it should be possible to more or less merge the base-derived stuff and delegating stuff. Would have to rename stuff a bit, but the cases are pretty much identical. In fact, when testing I simply used the code for the base-derived stuff as-is and just made it also apply to delegating constructors.

I can do this in this PR if you want.

Interesting. I'd imagined that the base-derived stuff (which should be invoked recursively, and in addition in a sequence for all the base classes, which it doesn't do right now, I believe) was sufficiently different from delegating. And delegations could also take multiple levels, with each having their own body. Probably best to experiment with that in another PR. I'm happy with it.

Copy link
Contributor

@lucasccordeiro lucasccordeiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting this PR, @intrigus-lgtm.

As suggested by @fbrausse, it would be great if you could experiment with the improvement described here in another PR.

@lucasccordeiro lucasccordeiro merged commit cb9ab75 into esbmc:master Mar 20, 2024
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants