Coccinelle C++ Tests Results Summary

CPPREFERENCE AND TESTS:

https://en.cppreference.com/w/cpp/cpp/types/size_tsizet
https://en.cppreference.com/w/cpp/header/complexcomplexcpp*
https://en.cppreference.com/w/cpp/keyword/notnotpp
https://en.cppreference.com/w/cpp/language/accessaccess_specifiers_4 access_specifiers_0 access_specifiers_1 access_specifiers_2 access_specifiers_3 snip_field_and_keep_access_specifier destructor_constructor_parse_smpl* access_specifiers_1_class* destructor_constructor_parse*
https://en.cppreference.com/w/cpp/language/aggregate_initialization#Syntaxlist_and_aggregate_initialization_isomorphism_on list_and_aggregate_initialization_isomorphism_off list_initialization bracket aggregate_initialization* init3tst bracketed_expression_assignment* match_bracket_expressions_assignment_broken*
https://en.cppreference.com/w/cpp/language/attributesattributeu*
https://en.cppreference.com/w/cpp/language/autoauto*
https://en.cppreference.com/w/cpp/language/catchtry_catch try_catch1* try_catch2
https://en.cppreference.com/w/cpp/language/classsnip_field_bad snip_field snip_field_and_keep_access_specifier destructor_constructor_parse_smpl* access_specifiers_1_class* miniclass destructor_constructor_parse*
https://en.cppreference.com/w/cpp/language/constructorcdstr
https://en.cppreference.com/w/cpp/language/decltypedecltype_matches_type decltype
https://en.cppreference.com/w/cpp/language/delete#Syntaxdelete_array delete
https://en.cppreference.com/w/cpp/language/derived_classinh1 qualclass
https://en.cppreference.com/w/cpp/language/destructorvconstr* destructor_constructor_parse_smpl* virtual_constructor* destructor_constructor_parse*
https://en.cppreference.com/w/cpp/language/enumenumcpp
https://en.cppreference.com/w/cpp/language/explicit_cast#Explanationbraced_init_list
https://en.cppreference.com/w/cpp/language/finalclassfinal*
https://en.cppreference.com/w/cpp/language/final#Syntaxfinalclass
https://en.cppreference.com/w/cpp/language/function#Function_definitioncuda
https://en.cppreference.com/w/cpp/language/functionbool1 braced_init_list_arg
https://en.cppreference.com/w/cpp/language/initialization#Initializerbraced_init_list_assign braced_init_list_arg
https://en.cppreference.com/w/cpp/language/namespace_aliasnamespace_alias_definition*
https://en.cppreference.com/w/cpp/language/namespacenamespace_nested4* namespace_nested1* namespace_nested2* namespace_nested3*
https://en.cppreference.com/w/cpp/language/new#Syntaxnew* newsimple new3* new2*
https://en.cppreference.com/w/cpp/language/noexcept_specnoexcept*
https://en.cppreference.com/w/cpp/language/operator_member_accessfieldtmp*
https://en.cppreference.com/w/cpp/language/operator_other#Built-in_function_call_operatorcuda1 cuda_noattr
https://en.cppreference.com/w/cpp/language/operatorsopeq*
https://en.cppreference.com/w/cpp/language/partial_specializationtemplates_partial_specialization*
https://en.cppreference.com/w/cpp/language/pointer#Pointersdecl_ptr_ref
https://en.cppreference.com/w/cpp/language/qualified_lookupendcolon qual qualclass endline
https://en.cppreference.com/w/cpp/language/range-forforrange2 forrange autoloop
https://en.cppreference.com/w/cpp/language/reference#Rvalue_referencesprotocpp decl_and_ref decl_andand_ref
https://en.cppreference.com/w/cpp/language/returnbraced_init_list_return
https://en.cppreference.com/w/cpp/language/template_parameters#Template_argumentstemplates_partial_specialization* forc instfour* emptytmp* tmpinst4* tmpinst5* tmpinst2* tmpinit endline template_test* tempinstfour* templates1* addremvec*
https://en.cppreference.com/w/cpp/language/trytry_catch try_catch1* try_catch2
https://en.cppreference.com/w/cpp/language/using_declarationinstruct usingtest* usingtype using1 using3 using2* using4*
https://en.cppreference.com/w/cpp/language/virtualvconstr* virtual_constructor*
https://en.cppreference.com/w/cpp/language/whilewhile_init_condition_smpl while_init_condition
https://en.cppreference.com/w/cpp/numeric/complexcomplexcpp*
https://en.cppreference.com/w/cpp/preprocessorlocal_macro_fn_def_and_call macro_stmt_when_fn_type
https://en.cppreference.com/w/cpp/preprocessor/implinstruct

TEST CASE BROKEN (spatch ... exits non-zero): 11/93

access_specifiers_1_class aggregate_initialization destructor_constructor_parse_smpl namespace_nested2 namespace_nested3 namespace_nested4 new new2 new3 templates_partial_specialization vconstr

TEST FAILS (patches differ): 37/93

access_specifiers_1_class addremvec aggregate_initialization attributeu auto bracketed_expression_assignment classfinal complexcpp destructor_constructor_parse destructor_constructor_parse_smpl emptytmp fieldtmp instfour match_bracket_expressions_assignment_broken namespace_alias_definition namespace_nested1 namespace_nested2 namespace_nested3 namespace_nested4 new new2 new3 noexcept opeq tempinstfour templates1 templates_partial_specialization template_test tmpinst2 tmpinst4 tmpinst5 try_catch1 using2 using4 usingtest vconstr virtual_constructor

PASSED SPATCH PARSE: 84/93

access_specifiers_0 access_specifiers_1 access_specifiers_2 access_specifiers_3 access_specifiers_4 addremvec attributeu auto autoloop bool1 braced_init_list braced_init_list_arg braced_init_list_assign braced_init_list_return bracket bracketed_expression_assignment cdstr classfinal complexcpp cuda cuda1 cuda_noattr decl_andand_ref decl_and_ref decl_ptr_ref decltype decltype_matches_type delete delete_array destructor_constructor_parse emptytmp endcolon endline enumcpp fieldtmp finalclass forc forrange forrange2 inh1 init3tst instfour instruct list_and_aggregate_initialization_isomorphism_off list_and_aggregate_initialization_isomorphism_on list_initialization local_macro_fn_def_and_call macro_stmt_when_fn_type match_bracket_expressions_assignment_broken miniclass namespace_alias_definition namespace_nested1 new newsimple noexcept notpp opeq protocpp qual qualclass sizet snip_field snip_field_and_keep_access_specifier snip_field_bad tempinstfour templates1 template_test tmpinit tmpinst2 tmpinst4 tmpinst5 try_catch try_catch1 try_catch2 using1 using2 using3 using4 usingtest usingtype vconstr virtual_constructor while_init_condition while_init_condition_smpl

FAILED SPATCH PARSE: 9/93

access_specifiers_1_class aggregate_initialization destructor_constructor_parse_smpl namespace_nested2 namespace_nested3 namespace_nested4 new2 new3 templates_partial_specialization

PASSED SOURCE PARSE: 66/93

access_specifiers_0 access_specifiers_1 access_specifiers_1_class access_specifiers_2 access_specifiers_3 access_specifiers_4 aggregate_initialization attributeu autoloop bool1 braced_init_list braced_init_list_arg braced_init_list_assign braced_init_list_return bracket bracketed_expression_assignment cdstr complexcpp cuda cuda1 cuda_noattr decl_andand_ref decl_and_ref decl_ptr_ref decltype decltype_matches_type delete delete_array destructor_constructor_parse destructor_constructor_parse_smpl endcolon endline enumcpp finalclass forc inh1 init3tst instruct list_and_aggregate_initialization_isomorphism_off list_and_aggregate_initialization_isomorphism_on list_initialization local_macro_fn_def_and_call match_bracket_expressions_assignment_broken miniclass newsimple notpp qual qualclass sizet snip_field snip_field_and_keep_access_specifier snip_field_bad templates1 template_test tmpinit try_catch try_catch1 try_catch2 using1 using2 using3 using4 vconstr virtual_constructor while_init_condition while_init_condition_smpl

FAILED SOURCE PARSE: 27/93

addremvec auto classfinal emptytmp fieldtmp forrange forrange2 instfour macro_stmt_when_fn_type namespace_alias_definition namespace_nested1 namespace_nested2 namespace_nested3 namespace_nested4 new new2 new3 noexcept opeq protocpp tempinstfour templates_partial_specialization tmpinst2 tmpinst4 tmpinst5 usingtest usingtype

PASSED TEST RUNS: 82/93

access_specifiers_0 access_specifiers_1 access_specifiers_2 access_specifiers_3 access_specifiers_4 addremvec attributeu auto autoloop bool1 braced_init_list braced_init_list_arg braced_init_list_assign braced_init_list_return bracket bracketed_expression_assignment cdstr classfinal complexcpp cuda cuda1 cuda_noattr decl_andand_ref decl_and_ref decl_ptr_ref decltype decltype_matches_type delete delete_array destructor_constructor_parse emptytmp endcolon endline enumcpp fieldtmp finalclass forc forrange forrange2 inh1 init3tst instfour instruct list_and_aggregate_initialization_isomorphism_off list_and_aggregate_initialization_isomorphism_on list_initialization local_macro_fn_def_and_call macro_stmt_when_fn_type match_bracket_expressions_assignment_broken miniclass namespace_alias_definition namespace_nested1 newsimple noexcept notpp opeq protocpp qual qualclass sizet snip_field snip_field_and_keep_access_specifier snip_field_bad tempinstfour templates1 template_test tmpinit tmpinst2 tmpinst4 tmpinst5 try_catch try_catch1 try_catch2 using1 using2 using3 using4 usingtest usingtype virtual_constructor while_init_condition while_init_condition_smpl

FAILED TEST RUNS: 11/93

access_specifiers_1_class aggregate_initialization destructor_constructor_parse_smpl namespace_nested2 namespace_nested3 namespace_nested4 new new2 new3 templates_partial_specialization vconstr

SOURCES FOR ALL TESTS: 93

Test: access_specifiers_0 (PASS)

access_specifiers_0.cocci :
# spatch --c++
// can't remove existing non-existing 'private' access specifier
@@ @@
  struct A {
-       private:
  };
access_specifiers_0.cpp :
struct A {
        public:
};
access_specifiers_0.res :
struct A {
        public:
};

Test: access_specifiers_1 (PASS)

access_specifiers_1.cocci :
# spatch --c++
// remove existing 'public' access specifier
@@ @@
  struct A {
-       public:
  };
access_specifiers_1.cpp :
struct A {
        public:
};
access_specifiers_1.res :
struct A {
};

Test: access_specifiers_1_class (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci)

access_specifiers_1_class.cocci :
# spatch --c++
// remove existing 'public' access specifier
@@ @@
  class A {
-       public:
  };
access_specifiers_1_class.cpp :
class A {
        public:
};
access_specifiers_1_class.res :
class A {
};

Test: access_specifiers_2 (PASS)

access_specifiers_2.cocci :
# spatch --c++
// FIXME: broken
// 'public' specifier required to be there in code in order to match
@@ @@
  struct A {
        public:
// note: inserting only a comment would go unnoticed by coccinelle
+       int a;// after public
  };
access_specifiers_2.cpp :
struct A {
        public:
};
access_specifiers_2.res :
struct A {
        public:
        int a;// after public
};

Test: access_specifiers_3 (PASS)

access_specifiers_3.cocci :
# spatch --c++
// FIXME: broken
// add next to 'public' access specifier
@@ @@
  struct A {
        public:
+       private:
  };
access_specifiers_3.cpp :
struct A {
        public:
};
access_specifiers_3.res :
struct A {
        public:
        private:
};

Test: access_specifiers_4 (PASS)

access_specifiers_4.cocci :
# spatch --c++
// remove 'public' access specifier and add 'private'
@@ @@
  struct A {
-       public:
+       private:
  };
access_specifiers_4.cpp :
struct A {
        public:
};
access_specifiers_4.res :
struct A {
        private:
};

Test: addremvec (FAIL: /*patch differs*/ --parse-c)

addremvec.cocci :
# spatch --c++
@@
symbol d;
@@
- vector<f(1, 2)>
+ vector<f(12, 2)>
  d;
addremvec.cpp :
vector<f(1, 2)> d;
addremvec.res :
vector<f(12, 2)> d;

Test: aggregate_initialization (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci)

aggregate_initialization.cocci :
# spatch --c++
@@
symbol i;
@@
-       int i{0};
aggregate_initialization.cpp :
int main()
{
        int i {0};
}
aggregate_initialization.res :
int main()
{
}

Test: attributeu (FAIL: /*patch differs*/)

attributeu.cocci :
# spatch --c++
@@
symbol variable;
@@
- [[using GCC:lucky,...]]
+ [[using CCG:fortunate]]
 int variable;
attributeu.cpp :
int main(){
        [[using GCC : lucky]] int variable;
}
attributeu.res :
int main(){
        [[using CCG:fortunate]] int variable;
}

Test: auto (FAIL: /*patch differs*/ --parse-c)

auto.cocci :
# spatch --c++=11

@@
type t;
identifier x, y;
@@
- type y = x;
+ type x = y;

@@
type t;
identifier x;
@@
- t x = 2;
+ auto y = 2;
auto.cpp :
int main() {
  auto x = 2;
  const auto& y = x;
  return 0;
}
auto.res :
int main() {
  auto y = 2;
  const auto& x = y;
  return 0;
}

Test: autoloop (PASS)

autoloop.cocci :
# spatch --c++=11
@rule1@
type T;
identifier i,a;
statement s;
@@
- for (T i=0; i<sizeof(a); ++i)
+ for (auto ae: a)
  {
    s
  }

@rule2@
expression e;
identifier rule1.a;
identifier rule1.i;
statement  rule1.s;
@@
(
- a[i]
+ ae
&
 e@s
)
autoloop.cpp :
int main () {
  for (int i=0; i<sizeof(a); ++i) {
     a[i]++;
  }
}
autoloop.res :
int main () {
  for (auto ae: a) {
     ae++;
  }
}

Test: bool1 (PASS)

bool1.cocci :
# spatch --c++
@@
@@

- 0
+ 1
bool1.cpp :
atype f::g() {
  return 0;
}
bool1.res :
atype f::g() {
  return 1;
}

Test: braced_init_list (PASS)

braced_init_list.cocci :
# spatch --c++
@ identifier@
@@
- i
+ j
braced_init_list.cpp :
int main()
{
        int i;
        i = {0};
}
braced_init_list.res :
int main()
{
        int j;
        j = {0};
}

Test: braced_init_list_arg (PASS)

braced_init_list_arg.cocci :
# spatch --c++
// remove a function argument braced-init-list
@@
@@
- f({0});
braced_init_list_arg.cpp :
struct A {int i;};
void f(A){}
int main()
{
        A i{0};
        i={0};
        f({0});
        return {0};
}
braced_init_list_arg.res :
struct A {int i;};
void f(A){}
int main()
{
        A i{0};
        i={0};
        return {0};
}

Test: braced_init_list_assign (PASS)

braced_init_list_assign.cocci :
# spatch --c++
// remove an assignment of a braced-init-list (initializer-list within brackets)
@@
@@
- i = {0};
braced_init_list_assign.cpp :
struct A {int i;};
int main()
{
        A i{0};
        i={0};
        return {0};
}
braced_init_list_assign.res :
struct A {int i;};
int main()
{
        A i{0};
        return {0};
}

Test: braced_init_list_return (PASS)

braced_init_list_return.cocci :
# spatch --c++
// remove a return braced-init-list
@@
@@
- return {0};
braced_init_list_return.cpp :
struct A {int i;};
int main()
{
        A i{0};
        i={0};
        return {0};
}
braced_init_list_return.res :
struct A {int i;};
int main()
{
        A i{0};
        i={0};
}

Test: bracket (PASS)

bracket.cocci :
# spatch --c++
@@
symbol flags_;
@@

- flags_
+ 12
bracket.cpp :
int main () {
  rsb_flags_t flags{flags_};
}
bracket.res :
int main () {
  rsb_flags_t flags{12};
}

Test: bracketed_expression_assignment (FAIL: /*patch differs*/)

bracketed_expression_assignment.cocci :
# spatch --c++=11
// FIXME: expression e does not currently see {1} as an expression
@@
identifier i;
expression e;
@@
+ // specific identifier matched:
i = e;
bracketed_expression_assignment.cpp :
int main() {
        int j;
        j = {1};
}
bracketed_expression_assignment.res :
int main() {
        int j;
// specific identifier matched:
        j = {1};
}

Test: cdstr (PASS)

cdstr.cocci :
# spatch --c++
@identifier@
symbol a;
@@

- a
+ aa
cdstr.cpp :
// https://en.cppreference.com/w/cpp/language/constructor

class X
{
    int a, b, i, j;
public:
    const int& r;
    X(int i)
      : r(a) // initializes X::r to refer to X::a
      , b{i} // initializes X::b to the value of the parameter i
      , i(i) // initializes X::i to the value of the parameter i
      , j(this->i) // initializes X::j to the value of X::i
    {}
};
cdstr.res :
// https://en.cppreference.com/w/cpp/language/constructor

class X
{
    int aa, b, i, j;
public:
    const int& r;
    X(int i)
      : r(aa) // initializes X::r to refer to X::a
      , b{i} // initializes X::b to the value of the parameter i
      , i(i) // initializes X::i to the value of the parameter i
      , j(this->i) // initializes X::j to the value of X::i
    {}
};

Test: classfinal (FAIL: /*patch differs*/ --parse-c)

classfinal.cocci :
# spatch --c++
@identifier@
symbol x;
@@

- x
+ y
classfinal.cpp :
class FreeEnergyPerturbationData::Element final :
     public ISimulatorElement,
     public ICheckpointHelperClient,
     public IDomDecHelperClient
 {
 public:
  int x;
 };
classfinal.res :
class FreeEnergyPerturbationData::Element final :
     public ISimulatorElement,
     public ICheckpointHelperClient,
     public IDomDecHelperClient
 {
 public:
  int y;
 };

Test: complexcpp (FAIL: /*patch differs*/)

complexcpp.cocci :
# spatch --c++
@@
type T;
identifier x;
@@

- T x;
complexcpp.cpp :
int main() {
  std::complex<double> x;
}
complexcpp.res :
int main() {
}

Test: cuda (PASS)

cuda.cocci :
# spatch --c++
@@
identifier kernel;
@@

+ // CUDA follows
  kernel<<< gridDim, blockDim, 0 >>>();
cuda.cpp :
__global__ void kernel_1()
{
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
}

__global__ void kernel_2(int i)
{
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
}

int main()
{
       dim3 blockDim(16, 16, 1);
       dim3 gridDim(8, 8, 1);
       kernel_2<<< gridDim, blockDim, 0 >>>();
       kernel_1< gridDim, blockDim, 0 >();
       f();
       return 0;
}
cuda.res :
__global__ void kernel_1()
{
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
}

__global__ void kernel_2(int i)
{
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
}

int main()
{
       dim3 blockDim(16, 16, 1);
       dim3 gridDim(8, 8, 1);
       // CUDA follows
       kernel_2<<< gridDim, blockDim, 0 >>>();
       kernel_1< gridDim, blockDim, 0 >();
       f();
       return 0;
}

Test: cuda1 (PASS)

cuda1.cocci :
# spatch --c++
@@
expression e;
@@

- e();
+ e(0);
cuda1.cpp :
int main()
{
        kernel_2<<<gridDim, blockDim, 0>>>();
}
cuda1.res :
int main()
{
        kernel_2<<<gridDim, blockDim, 0>>>(0);
}

Test: cuda_noattr (PASS)

cuda_noattr.cocci :
# spatch --c++
@@
// attribute name __global__; // not needed
@@

void kernel_2(...) { 
+ 1;
 ...
 }
cuda_noattr.cpp :
__global__ void kernel_2(int i)
{
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
}

int main()
{
        return 0;
}
cuda_noattr.res :
__global__ void kernel_2(int i)
{
   1;
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
}

int main()
{
        return 0;
}

Test: decl_andand_ref (PASS)

decl_andand_ref.cocci :
#spatch --c++
@@
@@
  int && b = 0;
+ // reference matched above
decl_andand_ref.cpp :
int main()
{
        int   v = 0;
        int   a = 0;
        int && b = 0;
}
decl_andand_ref.res :
int main()
{
        int   v = 0;
        int   a = 0;
        int && b = 0;
        // reference matched above
}

Test: decl_and_ref (PASS)

decl_and_ref.cocci :
#spatch --c++
@@
@@
  int & b = v;
+ // reference matched above
decl_and_ref.cpp :
int main()
{
        int   v = 0;
        int   a = 0;
        int & b = v;
}
decl_and_ref.res :
int main()
{
        int   v = 0;
        int   a = 0;
        int & b = v;
        // reference matched above
}

Test: decl_ptr_ref (PASS)

decl_ptr_ref.cocci :
#spatch --c++
@@
@@
  int * b = &v;
+ // pointer matched above
decl_ptr_ref.cpp :
int main()
{
        int   v = 0;
        int   a = 0;
        int * b = &v;
}
decl_ptr_ref.res :
int main()
{
        int   v = 0;
        int   a = 0;
        int * b = &v;
        // pointer matched above
}

Test: decltype (PASS)

decltype.cocci :
# spatch --c++
@@
idexpression int x;
@@

return <+...
- x
+ 12
 ...+>
 ;

@@
idexpression int *x;
@@

return <+...
- x
+ 0
 ...+>
 ;
decltype.cpp :
int expr;

int main () {
  decltype(expr) expr2;
  decltype((expr)) expr3;
  return expr2 + expr3;
}
decltype.res :
int expr;

int main () {
  decltype(expr) expr2;
  decltype((expr)) expr3;
  return 12 + expr3;
}

Test: decltype_matches_type (PASS)

decltype_matches_type.cocci :
# spatch --c++
@@
type T;
identifier i;
fresh identifier n = i ## "_";
@@

- T i;
+ T n;
decltype_matches_type.cpp :
int expr;

int main () {
  int i;
  decltype(i) j;
  return 0;
}
decltype_matches_type.res :
int expr_;

int main () {
  int i_;
  decltype(i) j_;
  return 0;
}

Test: delete (PASS)

delete.cocci :
# spatch --c++
@@
expression e;
@@
- delete e;
delete.cpp :
int main()
{
        int * a;
        delete a;
        delete [] a;
}
delete.res :
int main()
{
        int * a;
        delete [] a;
}

Test: delete_array (PASS)

delete_array.cocci :
# spatch --c++
@@
expression e;
@@
- delete [] e;
delete_array.cpp :
int main()
{
        int * a;
        delete a;
        delete [] a;
}
delete_array.res :
int main()
{
        int * a;
        delete a;
}

Test: destructor_constructor_parse (FAIL: /*patch differs*/)

destructor_constructor_parse.cocci :
#spatch --c++
@@
@@
- 0;
+ 1;
destructor_constructor_parse.cpp :
struct A {
        public:
         A(){0;}
        ~A(){0;}
        void a(){0;}
};
int main(){
        A a;
        0;
}
destructor_constructor_parse.res :
struct A {
        public:
         A(){1;}
        ~A(){1;}
        void a(){1;}
};
int main(){
        A a;
        1;
}

Test: destructor_constructor_parse_smpl (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci)

destructor_constructor_parse_smpl.cocci :
#spatch --c++
@@
@@
struct A {
-       public:
-        A(){}
-       ~A(){}
-       void a(){}
};
destructor_constructor_parse_smpl.cpp :
struct A {
        public:
         A(){}
        ~A(){}
        void a(){}
};
int main(){
        A a;
}
destructor_constructor_parse_smpl.res :
struct A {
};
int main(){
        A a;
}

Test: emptytmp (FAIL: /*patch differs*/ --parse-c)

emptytmp.cocci :
# spatch --c++
@@
@@

- 1
+ 2
emptytmp.cpp :
int x;

template<>
class TestSpMM_OfAnyTypeSquare: public SquareTestMatrix<std::tuple_element_t<0,TV>,std::tuple_element_t<1,TV>>, public ::testing::Test {
 public:
  using NT = typename std::tuple_element_t<0,TV>;
  using IT = typename std::tuple_element_t<1,TV>;
  using Parms = typename std::tuple_element_t<2,TV>;
  using MtxP = SquareTestMatrix <NT,IT>;
  int x[1];
};
emptytmp.res :
int x;

template<>
class TestSpMM_OfAnyTypeSquare: public SquareTestMatrix<std::tuple_element_t<0,TV>,std::tuple_element_t<2,TV>>, public ::testing::Test {
 public:
  using NT = typename std::tuple_element_t<0,TV>;
  using IT = typename std::tuple_element_t<2,TV>;
  using Parms = typename std::tuple_element_t<2,TV>;
  using MtxP = SquareTestMatrix <NT,IT>;
  int x[2];
};

Test: endcolon (PASS)

endcolon.cocci :
# spatch --c++
@@
@@

- 12
+ 15
endcolon.cpp :
int main () {
        a::b :: c ::
        d(12);
}
endcolon.res :
int main () {
        a::b :: c ::
        d(15);
}

Test: endline (PASS)

endline.cocci :
# spatch --c++
@@
@@

- 12
+ 15
endline.cpp :
int main() {
        std::vector<abc>::
        t x = 12;
}
endline.res :
int main() {
        std::vector<abc>::
        t x = 15;
}

Test: enumcpp (PASS)

enumcpp.cocci :
#spatch --c++=11

@@ identifier l1, l2, l3, l4, l11, l12, l13, l14, l21, l22, l33, l32, zl1, zl2, zl3, zl4, zl11, zl12, zl13, zl14, zl21, zl22, zl33, zl32; @@

-  enum struct l1 {A, B};
-  enum class  l2 {A2, B2};
-  enum struct l3:int {A3,B3};
-  enum class  l4:int {A4,B4};

-  enum l11 {A11, B11};
-  enum l12 {A12, B12};
-  enum l13:int {A13,B13};
-  enum l14:int {A14,B14};

-  enum {A21, B21} l21;
-  enum {A22, B22} l22;
-  enum :int {A33,B33} l33;
-  enum :int {A32,B32} l32;

-  enum struct zl1 {};
-  enum class  zl2 {};
-  enum struct zl3:int {};
-  enum class  zl4:int {};

-  enum zl11 {};
-  enum zl12 {};
-  enum zl13:int {};
-  enum zl14:int {};

-  enum {} zl21;
-  enum {} zl22;
-  enum :int {} zl33;
-  enum :int {} zl32;
enumcpp.cpp :
int main()
{
  enum struct l1 {A, B};
  enum class  l2 {A2, B2};
  enum struct l3:int {A3,B3};
  enum class  l4:int {A4,B4};

  enum l11 {A11, B11};
  enum l12 {A12, B12};
  enum l13:int {A13,B13};
  enum l14:int {A14,B14};

  enum {A21, B21} l21;
  enum {A22, B22} l22;
  enum :int {A33,B33} l33;
  enum :int {A32,B32} l32;

  enum struct zl1 {};
  enum class  zl2 {};
  enum struct zl3:int {};
  enum class  zl4:int {};

  enum zl11 {};
  enum zl12 {};
  enum zl13:int {};
  enum zl14:int {};

  enum {} zl21;
  enum {} zl22;
  enum :int {} zl33;
  enum :int {} zl32;
}
enumcpp.res :
int main()
{
}

Test: fieldtmp (FAIL: /*patch differs*/ --parse-c)

fieldtmp.cocci :
# spatch --c++
@@
@@

- 0
+ 2
fieldtmp.cpp :
int main2() {
  errval = mtx.tune_spmm<rsb_err_t>(nullptr,0);
}
fieldtmp.res :
int main2() {
  errval = mtx.tune_spmm<rsb_err_t>(nullptr,2);
}

Test: finalclass (PASS)

finalclass.cocci :
# spatch --c++
@identifier@
identifier x;
symbol y;
@@

-x
+y
finalclass.cpp :
class foo final { int x; };
finalclass.res :
class foo final { int y; };

Test: forc (PASS)

forc.cocci :
#spatch --c++

@@
expression e1,e2;
@@

- e1 > e2
+ 12
forc.cpp :
static void Ptngc_widediv()
{
  while (rmask)
    {
      if ((s_U<hi) || ((s_U==hi) && (s_L<=lo)))
        {
          if (s_L>lo)
            {
              unsigned int t;
              hi--; /* Borrow */
            }
        }
    }
}
forc.res :
static void Ptngc_widediv()
{
  while (rmask)
    {
      if ((12) || ((s_U==hi) && (s_L<=lo)))
        {
          if (12)
            {
              unsigned int t;
              hi--; /* Borrow */
            }
        }
    }
}

Test: forrange (FAIL: --parse-c)

forrange.cocci :
# spatch --c++=11
@@
identifier i, IA;
statement S;
@@

- for (auto i: IA)
+ for (auto x: IA)
  S
forrange.cpp :
int main () {
 for (auto i: IA)
   x = 12;
}
forrange.res :
int main () {
 for (auto x: IA)
   x = 12;
}

Test: forrange2 (FAIL: --parse-c)

forrange2.cocci :
# spatch --c++
@@
@@

- 2
+ 4
forrange2.cpp :
m2n::PtrM2N M2NConfiguration::getM2N(const std::string &acceptor, const std::string &connector)
{
  using std::get;
  for (M2NTuple &tuple : _m2ns) {
    if ((get<1>(tuple) == acceptor) && (get<2>(tuple) == connector)) {
      return get<0>(tuple);
    } else if ((get<2>(tuple) == acceptor) && (get<1>(tuple) == connector)) {
      return get<0>(tuple);
    }
  }
  PRECICE_ERROR("There is no m2n communication configured between participants \"" + acceptor + "\" and \"" + connector + "\". Please add an appropriate \"<m2n />\" tag.");
}
forrange2.res :
m2n::PtrM2N M2NConfiguration::getM2N(const std::string &acceptor, const std::string &connector)
{
  using std::get;
  for (M2NTuple &tuple : _m2ns) {
    if ((get<1>(tuple) == acceptor) && (get<4>(tuple) == connector)) {
      return get<0>(tuple);
    } else if ((get<4>(tuple) == acceptor) && (get<1>(tuple) == connector)) {
      return get<0>(tuple);
    }
  }
  PRECICE_ERROR("There is no m2n communication configured between participants \"" + acceptor + "\" and \"" + connector + "\". Please add an appropriate \"<m2n />\" tag.");
}

Test: inh1 (PASS)

inh1.cocci :
# spatch --c++
@@
@@
+//
struct A { 
 ...
};
inh1.cpp :
// emits warning on c++ file: 5: list of length 3 or 4 expected
#include <iostream>
using namespace std;
struct A { };
struct B : public A { };
int main()
{
}
inh1.res :
// emits warning on c++ file: 5: list of length 3 or 4 expected
#include <iostream>
using namespace std;
//
struct A { };
struct B : public A { };
int main()
{
}

Test: init3tst (PASS)

init3tst.cocci :
# spatch --c++
@@
@@

- 2
+ 20
init3tst.cpp :
class TestUpperTriangle {
 public:
  static constexpr rsb_coo_idx_t nrA { 2 };
};
init3tst.res :
class TestUpperTriangle {
 public:
  static constexpr rsb_coo_idx_t nrA { 20 };
};

Test: instfour (FAIL: /*patch differs*/ --parse-c)

instfour.cocci :
# spatch --c++
@@
type t;
identifier i;
@@
 t i;
 xxx();
+ int sss;
instfour.cpp :
int main()
{
        vc_t<vc_t<vc_t<vc_t<int>>>> v;
        xxx();
}
instfour.res :
int main()
{
        vc_t<vc_t<vc_t<vc_t<int>>>> v;
        xxx();
        int sss;
}

Test: instruct (PASS)

instruct.cocci :
# spatch --c++
@@
identifier i;
@@

struct i {
  ...
- using namespace foo;
  ...
};

@@
identifier i;
@@

struct i {
  ...
- #pragma XXX yyy
  ...
};
instruct.cpp :
struct i {
  using namespace foo;
  int a;
};

struct j {
  #pragma XXX yyy
  int x;
};
instruct.res :
struct i {
  int a;
};

struct j {
  int x;
};

Test: list_and_aggregate_initialization_isomorphism_off (PASS)

list_and_aggregate_initialization_isomorphism_off.cocci :
# spatch --c++=11
@ disable list_and_aggregate_initialization@
identifier i;
@@
- int i={0};
list_and_aggregate_initialization_isomorphism_off.cpp :
int main()
{
        int i {0};
        int j={0};
}
list_and_aggregate_initialization_isomorphism_off.res :
int main()
{
        int i {0};
}

Test: list_and_aggregate_initialization_isomorphism_on (PASS)

list_and_aggregate_initialization_isomorphism_on.cocci :
# spatch --c++=11
@@
identifier i;
@@
- int i={0};
list_and_aggregate_initialization_isomorphism_on.cpp :
int main()
{
        int i {0};
        int j={0};
}
list_and_aggregate_initialization_isomorphism_on.res :
int main()
{
}

Test: list_initialization (PASS)

list_initialization.cocci :
# spatch --c++
@@
symbol j;
@@
-       int j={0};
list_initialization.cpp :
int main()
{
        int j={0};
}
list_initialization.res :
int main()
{
}

Test: local_macro_fn_def_and_call (PASS)

local_macro_fn_def_and_call.cocci :
# spatch --c++
@@
statement S;
@@
* S
local_macro_fn_def_and_call.cpp :
void f(void) {
#define SEMICOLON() ;
  SEMICOLON()
#undef SEMICOLON
}

void g(void) {
#define SEMICOLON_HINT() MACROSTATEMENT
  SEMICOLON_HINT()
#undef SEMICOLON_HINT
}
local_macro_fn_def_and_call.res :
void f(void) {
#define SEMICOLON() ;
  SEMICOLON()
#undef SEMICOLON
}

void g(void) {
#define SEMICOLON_HINT() MACROSTATEMENT
  SEMICOLON_HINT()
#undef SEMICOLON_HINT
}

Test: macro_stmt_when_fn_type (FAIL: --parse-c)

macro_stmt_when_fn_type.cocci :
# spatch --c++=11

@@
statement S;
@@
* S
macro_stmt_when_fn_type.cpp :
#define APPLY_FOR_ROLE return;
#define APPLY_FOR_ROLE_HINT MACROSTATEMENT

void do_nothing(fn_type<void(void)> fn) {
  APPLY_FOR_ROLE;
  APPLY_FOR_ROLE_HINT;
}
macro_stmt_when_fn_type.res :
#define APPLY_FOR_ROLE return;
#define APPLY_FOR_ROLE_HINT MACROSTATEMENT

void do_nothing(fn_type<void(void)> fn) {
  APPLY_FOR_ROLE;
  APPLY_FOR_ROLE_HINT;
}

Test: match_bracket_expressions_assignment_broken (FAIL: /*patch differs*/)

match_bracket_expressions_assignment_broken.cocci :
# spatch --c++=11
// FIXME: TODO: this rule seemingly does not change the code because of the k = {1} presence
// It shall already match j = 1.
// And once {1} is recognized as an expression too, also k = {1}.
@@
identifier i;
expression e;
@@
+ // assign to value:
 i = e;
match_bracket_expressions_assignment_broken.cpp :
int main() {
        int j,k;
        j = 1;
        k = {1};
}
match_bracket_expressions_assignment_broken.res :
int main() {
        int j,k;
// assign to value:
        j = 1;
// assign to value:
        k = {1};
}

Test: miniclass (PASS)

miniclass.cocci :
# spatch --c++

@@
@@

- int
+ char
miniclass.cpp :
class foo {
public:
    int public_field;
    int public_func();
private:
    int private_field;
    int private_func();
protected:
    int protected_field;
    int protected_func();
};

int main () {

class foo {
public:
    int public_field;
    int public_func();
private:
    int private_field;
    int private_func();
protected:
    int protected_field;
    int protected_func();
};

}
miniclass.res :
class foo {
public:
    char public_field;
    char public_func();
private:
    char private_field;
    char private_func();
protected:
    char protected_field;
    char protected_func();
};

char main () {

class foo {
public:
    char public_field;
    char public_func();
private:
    char private_field;
    char private_func();
protected:
    char protected_field;
    char protected_func();
};

}

Test: namespace_alias_definition (FAIL: /*patch differs*/ --parse-c)

namespace_alias_definition.cocci :
#spatch --c++
// test for source parsing of namespace alias definitions (not passing yet)
@@ @@
int main()
{
  ...
+ return 0;
}
namespace_alias_definition.cpp :
namespace n1 {
  namespace n2 {
  };
};
int main()
{
  namespace nad = n1::n2;
}
namespace_alias_definition.res :
namespace n1 {
  namespace n2 {
  };
};
int main()
{
  namespace nad = n1::n2;
  return 0;
}

Test: namespace_nested1 (FAIL: /*patch differs*/ --parse-c)

namespace_nested1.cocci :
# spatch --c++
@ identifier@
@@
- B
+ C
namespace_nested1.cpp :
namespace A
{
        namespace B { };
};
int main() { }
namespace_nested1.res :
namespace A
{
        namespace C { };
};
int main() { }

Test: namespace_nested2 (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci --parse-c)

namespace_nested2.cocci :
# spatch --c++
@ identifier@
@@
- namespace B { };
+ namespace C { };
namespace_nested2.cpp :
namespace A
{
        namespace B { };
};
int main() { }
namespace_nested2.res :
namespace A
{
        namespace C { };
};
int main() { }

Test: namespace_nested3 (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci --parse-c)

namespace_nested3.cocci :
# spatch --c++
@ identifier@
@@
namespace A
{
- namespace ... { };
+ namespace C { };
};
namespace_nested3.cpp :
namespace A
{
        namespace B { };
};
int main() { }
namespace_nested3.res :
namespace A
{
        namespace C { };
};
int main() { }

Test: namespace_nested4 (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci --parse-c)

namespace_nested4.cocci :
# spatch --c++
@@
identifier a,b;
@@
namespace
- a
+ b
{
        namespace
-       b
+       a
        { };
};
namespace_nested4.cpp :
namespace A
{
        namespace B { };
};
int main() { }
namespace_nested4.res :
namespace B
{
        namespace A { };
};
int main() { }

Test: new (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-c)

new.cocci :
# spatch --c++
@@ type L; @@
-new (1) (L) (1);
@@ type L; @@
-new (1) (L) {1};
@@ type L; @@
-new (1) (L);
@@ type L; @@
-new (1) L (1);
@@ type L; @@
-new (1) L {1};
@@ type L; @@
-new (1) L;
@@ type L; @@
-new (L) (1);
@@ type L; @@
-new (L) {1};
@@ type L; @@
-new (L);
@@ type L; @@
-new L (1);
@@ type L; @@
-new L {1};
@@ type L; @@
-new L;
new.cpp :
#include <new>
void n1(){
  int x;
  int*m{&x};
  int&r(x);

  // new (placement_params) (type) [initializer]
  new (m) (int) (r);
  new (m) (int) {r};
  new (m) (int);

  // new (placement_params) type [initializer]
  new (m) int (r);
  new (m) int {r};
  new (m) int;
}
void n2(){
  // new (type)
  new (int);
}
void n3(){
  // new (type) initializer
  new (int) (1);
}
void n4(){
  // new (type) initializer
  new (int) {1};
}
void n5(){
  // new type
  new int;
}
void n6(){
  // new type [initializer]
  new int (1);
}
void n7(){
  // new type [initializer]
  new int {1};
}

int main()
{
        n1();
        n2();
        n3();
        n4();
        n5();
        n6();
        n7();
}
new.res :
class Ball
{};

int main()
{
}

Test: new2 (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci --parse-c)

new2.cocci :
# spatch --c++
@@ @@
-       int*a = new int(2);
@@ @@
-       int*b = new int[3];
@@ @@
-       int*c = new int[2] {1,2};
new2.cpp :
#include <cassert>
void n1() {
        // new type initializer
        int*a = new int(2);
        assert(a[0] == 2);
}
void n2() {
        // new type
        int*b = new int[3];
        assert(b);
}
void n3() {
        // new type initializer
        int*c = new int[2] {1,2};
        assert(c[0] == 1);
        assert(c[1] == 2);
}
int main()
{
        n1(); n2(); n3();
}
new2.res :

Test: new3 (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci --parse-c)

new3.cocci :
# spatch --c++
@@ @@
-       new A[3];
@@ @@
-       B*b=new B    {1,2};
@@ @@
-       new C    (3);
@@ @@
-       C*c=new C[2] {1,2};
@@ @@
-       new C*[2];
new3.cpp :
#include <cassert>
#include <iostream>
struct A { int i{4}; A(){}; };
struct B { int i,j; };
struct C { int i;C(int j):i{j}{}; };
void n1(){
        // new new-type
        new A[3];
}
void n2(){
        // new new-type initializer
        B*b=new B    {1,2};
        assert(b->j==2);
}
void n3(){
        // new new-type initializer
        new C    (3);
}
void n4(){
        // new new-type initializer
        C*c=new C[2] {1,2};
        assert(c[0].i==1);
        assert(c[1].i==2);
}
void n5(){
        // new new-type
        new C*[2];
}
int main()
{
        n1(); n2(); n3();
        n4(); n5();
}
new3.res :

Test: newsimple (PASS)

newsimple.cocci :
#spatch --c++

@@
expression E;
@@

int main()
{
...
        sizeof(E);
-       new int(1);
+       new int(2);
...
}
newsimple.cpp :
int main()
{
  sizeof(Test);
  new int(1);
}
newsimple.res :
int main()
{
  sizeof(Test);
  new int(2);
}

Test: noexcept (FAIL: /*patch differs*/ --parse-c)

noexcept.cocci :
# spatch --c++
@identifier@
symbol foo;
@@

- foo
+ bar

@identifier@
symbol loc;
@@

- loc
+ xyz

@identifier@
symbol args;
@@

- args
+ abc
noexcept.cpp :
void foo() noexcept {}

void Logger::trace(LogLocation loc, int mess) noexcept
{ }

void Logger::trace(LogLocation loc, std::string_view mess) noexcept
{ }

formatter_type create_formatter(boost::log::attribute_name const &name, args_map const &args) override
{ return NULL; }
noexcept.res :
void bar() noexcept {}

void Logger::trace(LogLocation xyz, int mess) noexcept
{ }

void Logger::trace(LogLocation xyz, std::string_view mess) noexcept
{ }

formatter_type create_formatter(boost::log::attribute_name const &name,
                                args_map const &abc) override
{ return NULL; }

Test: notpp (PASS)

notpp.cocci :
# spatch --c++
@@
symbol m2n;
@@

- m2n
+ xxx
notpp.cpp :
void main () {
  if (not m2n->usesTwoLevelInitialization())
     return;
}
notpp.res :
void main () {
  if (not xxx->usesTwoLevelInitialization())
     return;
}

Test: opeq (FAIL: /*patch differs*/ --parse-c)

opeq.cocci :
# spatch --c++
@@
expression f;
@@

- f(...);
opeq.cpp :
inline bool operator==(const batch<T, A>& lhs, const std::array<T, N>& rhs)
     {
         std::array<T, N> tmp;
         lhs.store_unaligned(tmp.data());
         return tmp == rhs;
     }
opeq.res :
inline bool operator==(const batch<T, A>& lhs, const std::array<T, N>& rhs)
     {
         std::array<T, N> tmp;
         return tmp == rhs;
     }

Test: protocpp (FAIL: --parse-c)

protocpp.cocci :
# spatch --c++
@identifier@
symbol matcode;
@@

- matcode
+ xxx
protocpp.cpp :
int mm_write_banner(std::ofstream &ofs, MM_typecode matcode);
protocpp.res :
int mm_write_banner(std::ofstream &ofs, MM_typecode xxx);

Test: qual (PASS)

qual.cocci :
# spatch --c++
@@
symbol index;
@@

- index
+ 12
qual.cpp :
int main () {
  return std::isspace(text[index]);
}
qual.res :
int main () {
  return std::isspace(text[12]);
}

Test: qualclass (PASS)

qualclass.cocci :
# spatch --c++
@identifier@
symbol x;
@@

- x
+ y
qualclass.cpp :
class ResidualNorm : public ::testing::Test {
  int x;
};
qualclass.res :
class ResidualNorm : public ::testing::Test {
  int y;
};

Test: sizet (PASS)

sizet.cocci :
# spatch --c++
@@
identifier x;
@@

- size_t x;
sizet.cpp :
int main() {
  size_t x;
}
sizet.res :
int main() {
}

Test: snip_field (PASS)

snip_field.cocci :
# spatch --c++
@@
field lfld;
field list [n={2}] f2fld;
@@
struct str_t { 
- f2fld
  ...
- lfld
};
+ struct l_t { f2fld lfld };
snip_field.cpp :
struct str_t { int f1; int f2; int a; int b; };
int main() { }
snip_field.res :
struct str_t { int a; };
struct l_t {
        int f1;
        int f2;
        int b;
};
int main() { }

Test: snip_field_and_keep_access_specifier (PASS)

snip_field_and_keep_access_specifier.cocci :
#spatch --c++
@@
field lfld;
field list [n={2}] f2fld;
@@
struct str_t { 
- f2fld
  ...
- lfld
};
+ struct l_t { f2fld lfld };
snip_field_and_keep_access_specifier.cpp :
struct str_t { int f1; public: int f2; int a; int b; };
int main() { }
snip_field_and_keep_access_specifier.res :
struct str_t { int a; };
struct l_t {
        int f1;
        public:
        int f2;
        int b;
};
int main() { }

Test: snip_field_bad (PASS)

snip_field_bad.cocci :
#spatch --c++
@@
field lfld;
field list [n={2}] f2fld;
@@
struct str_t { 
- f2fld
  ...
- lfld
};
+ struct l_t { f2fld lfld };
snip_field_bad.cpp :
struct str_t { int f1; int f2; int a; int b; };
int main() { }
snip_field_bad.res :
struct str_t { int a; };
struct l_t {
        int f1;
        int f2;
        int b;
};
int main() { }

Test: tempinstfour (FAIL: /*patch differs*/ --parse-c)

tempinstfour.cocci :
# spatch --c++
@@
type t;
identifier i;
@@
- t i;
tempinstfour.cpp :
int main()
{
        vc_t<vc_t<vc_t<vc_t<int>>>> v;
}
tempinstfour.res :

Test: templates1 (FAIL: /*patch differs*/)

templates1.cocci :
# spatch --c++
@@
@@
- 4
+ 27
templates1.cpp :
template <typename T1, class T2=int, const int I1=4, T2 I2=1, const T2 I3=I1+I2>
int f(const T1 v1, const T2 v2)
{
        return I1+I2+I3+v1+v2;
}
int main()
{
        return f<int,int,4,1>(1,1) + f<int,int,-4,-1>(1,2) + f<int,int>(1,2) + f<int>(1,2) - 31;
}
templates1.res :
template <typename T1, class T2=int, const int I1=27, T2 I2=1, const T2 I3=I1+I2>
int f(const T1 v1, const T2 v2)
{
        return I1+I2+I3+v1+v2;
}
int main()
{
        return f<int,int,27,1>(1,1) + f<int,int,-27,-1>(1,2) + f<int,int>(1,2) + f<int>(1,2) - 31;
}

Test: templates_partial_specialization (FAIL: /*exits nonzero*/ /*patch differs*/ --test --parse-cocci --parse-c)

templates_partial_specialization.cocci :
#spatch --c++
// neither patch not source work yet
@@
@@

- template <class T> struct ts  { ... };
- template <> struct ts<int>  {
-       ...
- };

- template <> struct ts<int>::ns<int>  { ... };
- template <> int ts<int>::h<int>() { ... };

int main()
{
- ...
}
templates_partial_specialization.cpp :
template <class T> struct ts  {int f(){return 1;}};
template <> struct ts<int>  {
                template <class T> struct ns { int f(){return 2;} };
                template <class T> int h(){ return 3; }
};

template <> struct ts<int>::ns<int>  { int g(){return 0;}; }; // nested and templated struct
template <> int ts<int>::h<int>() { return 0; }; // nested and templated function

int main ()
{
        struct ts<int>::ns<int> v;
        struct ts<int> w;
        return v.g() + w.h<int>();
}
templates_partial_specialization.res :
int main ()
{
}

Test: template_test (FAIL: /*patch differs*/)

template_test.cocci :
# spatch --c++
@@
identifier i1;
type T1;
@@
        T1 i1;
+       vector<f(1, 2)> d;

@@
identifier i1;
type T1;
typedef xxx;
@@
        T1 i1;
+       xxx<g(3, 4)> d;

@@
symbol a,b;
identifier foo;
@@

- foo<12,a> (3, 4);
+ bar<102,b> (30, 40);

@type@
type x;
typedef abc;
@@

- x<g(...)>
+ abc<2 + 2>
template_test.cpp :
int min() {
  int x;
  foo<12,a> (3, 4);
  xxx<12,a> (3, 4);
  foo<12,a>(3, 4);
  xxx<12,a>(3, 4);
  foo<12,a>(3);
  xxx<12,a>(3);
}
template_test.res :
int min() {
  int x;
  abc<2 + 2> d;
  vector<f(1, 2)> d;
  abc<2 + 2> d;
  bar<102, b>(30, 40);
  bar<102, b>(30, 40);
  bar<102, b>(30, 40);
  bar<102, b>(30, 40);
  foo<12,a>(3);
  xxx<12,a>(3);
}

Test: tmpinit (PASS)

tmpinit.cocci :
# spatch --c++
@@
@@

- 4
+ 6
tmpinit.cpp :
class TestSymmetricCoo: public ::testing::Test {
  const std::vector<NT> VA { std::vector<NT>(nnzA,4) };
};
tmpinit.res :
class TestSymmetricCoo: public ::testing::Test {
  const std::vector<NT> VA { std::vector<NT>(nnzA,6) };
};

Test: tmpinst2 (FAIL: /*patch differs*/ --parse-c)

tmpinst2.cocci :
# spatch --c++
@@
type t;
identifier i;
@@
- t i;
tmpinst2.cpp :
int main2()
{
        vc_t<vc_t<int>> v;
}
tmpinst2.res :
int main2()
{
}

Test: tmpinst4 (FAIL: /*patch differs*/ --parse-c)

tmpinst4.cocci :
# spatch --c++
@@
type t;
identifier i;
@@
- t i;
tmpinst4.cpp :
int main()
{
        vc_t<int> v;
//      vc_t<vc_t<int>> v;
//      vc_t<vc_t<vc_t<int>>> v;
//      vc_t<vc_t<vc_t<vc_t<int>>>> v;
}
tmpinst4.res :
int main()
{
//      vc_t<vc_t<int>> v;
//      vc_t<vc_t<vc_t<int>>> v;
//      vc_t<vc_t<vc_t<vc_t<int>>>> v;
}

Test: tmpinst5 (FAIL: /*patch differs*/ --parse-c)

tmpinst5.cocci :
# spatch --c++
@@
type t;
identifier i;
@@
- t i;
tmpinst5.cpp :
int main1()
{
        vc_t<int> v;
}

int main2()
{
        vc_t<vc_t<int>> v;
}

int main3()
{
        vc_t<vc_t<vc_t<int>>> v;
}

int main4()
{
        vc_t<vc_t<vc_t<vc_t<int>>>> v;
}

int main5()
{
        vc_t<vc_t<vc_t<vc_t<vc_t<int>>>>> v;
}
tmpinst5.res :
int main1()
{
}

int main2()
{
}

int main3()
{
}

int main4()
{
}

int main5()
{
}

Test: try_catch (PASS)

try_catch.cocci :
#spatch --c++
@@
@@
int main ()
{
+ int i;
  ...
}
try_catch.cpp :
int main()
{
        try { }
        catch (int e) { }
}
try_catch.res :
int main()
{
        int i;
        try { }
        catch (int e) { }
}

Test: try_catch1 (FAIL: /*patch differs*/)

try_catch1.cocci :
#spatch --c++
@@
@@

- a();
+ b();
  ... when exists
  c();

@@
@@

m();

- n(); + x();
try_catch1.cpp :
int main()
{
        try { a(); m(); }
        catch (int e) { c(); }
        n();
}
try_catch1.res :

Test: try_catch2 (PASS)

try_catch2.cocci :
#spatch --c++
@@ @@
- {
-   a();
-   m();
- }
try_catch2.cpp :
int main()
{
        try { a(); m(); }
        catch (int e) { c(); }
        n();
}
try_catch2.res :
int main()
{
        try { a(); m(); }
        catch (int e) { c(); }
        n();
}

Test: using1 (PASS)

using1.cocci :
# spatch --c++
// using namespace ns-name;
@@
identifier i;
@@
- using namespace i;
using1.cpp :
namespace ns {};
int main()
{
        using namespace ns;
}
using1.res :
namespace ns {};
int main()
{
}

Test: using2 (FAIL: /*patch differs*/)

using2.cocci :
# spatch --c++
// using ns-name :: member-name;
@@
identifier i;
@@
- using i;
using2.cpp :
namespace ns { int x; };
int main()
{
        using ns::x;
}
using2.res :
namespace ns { int x; };
int main()
{
}

Test: using3 (PASS)

using3.cocci :
# spatch --c++
// namespace name = qualified-namespace;
@@
identifier i;
type t;
@@
- using i = t;
using3.cpp :
int main()
{
        using i_t = int;
        i_t i = 3;
}
using3.res :
int main()
{
        i_t i = 3;
}

Test: using4 (FAIL: /*patch differs*/)

using4.cocci :
# spatch --c++
// namespace name = qualified-namespace;
@@
identifier i;
type t;
@@
- using i = typename t;
using4.cpp :
// TODO: FIXME: will use 'std::vector<int>::value_type;' once template support is improved
int main()
{
        using s_t = typename std::string;
        s_t s;
}
using4.res :
// TODO: FIXME: will use 'std::vector<int>::value_type;' once template support is improved
int main()
{
        s_t s;
}

Test: usingtest (FAIL: /*patch differs*/ --parse-c)

usingtest.cocci :
# spatch --c++
@@
@@

- 1
+ 2
usingtest.cpp :
template <typename TV>
class TestSpMM_OfAnyTypeSquare: public SquareTestMatrix<std::tuple_element_t<0,TV>,std::tuple_element_t<6,TV>>, public ::testing::Test {
 public:
  using NT = typename std::tuple_element_t<0,TV>;
  using IT = typename std::tuple_element_t<6,TV>;
  using Parms = typename std::tuple_element_t<2,TV>;
  using MtxP = SquareTestMatrix <NT,IT>;
  int x[6];
};

template <typename TV>
class TestSpMM_OfAnyTypeSquare: public SquareTestMatrix<std::tuple_element_t<0,TV>,std::tuple_element_t<1,TV>>, public ::testing::Test {
 public:
  using NT = typename std::tuple_element_t<0,TV>;
  using IT = typename std::tuple_element_t<1,TV>;
  using Parms = typename std::tuple_element_t<2,TV>;
  using MtxP = SquareTestMatrix <NT,IT>;
  int x[1];
};

struct foo { int x[1]; };
usingtest.res :
template <typename TV>
class TestSpMM_OfAnyTypeSquare: public SquareTestMatrix<std::tuple_element_t<0,TV>,std::tuple_element_t<6,TV>>, public ::testing::Test {
 public:
  using NT = typename std::tuple_element_t<0,TV>;
  using IT = typename std::tuple_element_t<6,TV>;
  using Parms = typename std::tuple_element_t<2,TV>;
  using MtxP = SquareTestMatrix <NT,IT>;
  int x[6];
};

template <typename TV>
class TestSpMM_OfAnyTypeSquare: public SquareTestMatrix<std::tuple_element_t<0,TV>,std::tuple_element_t<2,TV>>, public ::testing::Test {
 public:
  using NT = typename std::tuple_element_t<0,TV>;
  using IT = typename std::tuple_element_t<2,TV>;
  using Parms = typename std::tuple_element_t<2,TV>;
  using MtxP = SquareTestMatrix <NT,IT>;
  int x[2];
};

struct foo { int x[2]; };

Test: usingtype (FAIL: --parse-c)

usingtype.cocci :
# spatch --c++
@type@
@@

- double
+ int
usingtype.cpp :
using mytime_t = double ;
usingtype.res :
using mytime_t = int ;

Test: vconstr (FAIL: /*exits nonzero*/ /*patch differs*/ --test)

vconstr.cocci :
#spatch --c++
@identifier@
symbol i,j;
@@
- i
+ j
vconstr.cpp :
struct A {
        int i;
        public:
        virtual  A(){int i;} // warning: constructors cannot be declared â€~virtualâ€TM; tolerable with e.g. g++ -fpermissive
        virtual ~A(){int i;} // destructors can be declared 'virtual'
};
int main(){
        int i;
        A a;
}
vconstr.res :
struct A {
        int j;
        public:
        virtual  A(){int j;} // warning: constructors cannot be declared â€~virtualâ€TM; tolerable with e.g. g++ -fpermissive
        virtual ~A(){int j;} // destructors can be declared 'virtual'
};
int main(){
        int j;
        A a;
}

Test: virtual_constructor (FAIL: /*patch differs*/)

virtual_constructor.cocci :
#spatch --c++
@@
symbol i,j;
@@
- int i;
virtual_constructor.cpp :
class A {
        public:
        virtual  A(){int i;} // warning: constructors cannot be declared â€~virtualâ€TM; tolerable with e.g. g++ -fpermissive
        virtual ~A(){int i;} // destructors can be declared 'virtual'
};
int main(){
        int i;
        A a;
}
virtual_constructor.res :
class A {
        public:
        virtual  A(){} // warning: constructors cannot be declared â€~virtualâ€TM; tolerable with e.g. g++ -fpermissive
        virtual ~A(){} // destructors can be declared 'virtual'
};
int main(){
        A a;
}

Test: while_init_condition (PASS)

while_init_condition.cocci :
# spatch --c++
@ identifier @
@@
- v
+ z
while_init_condition.cpp :
int main()
{
        const int a [] = {1,2,0};
        int i=0;
        while (const int v = a[i++])
                ;
}
while_init_condition.res :
int main()
{
        const int a [] = {1,2,0};
        int i=0;
        while (const int z = a[i++])
                ;
}

Test: while_init_condition_smpl (PASS)

while_init_condition_smpl.cocci :
# spatch --c++
@@
@@
- while (const int v = a[i++])
+ while (const int z = a[i++])
        ;
while_init_condition_smpl.cpp :
int main()
{
        const int a [] = {1,2,0};
        int i=0;
        while (const int v = a[i++])
                ;
}
while_init_condition_smpl.res :
int main()
{
        const int a [] = {1,2,0};
        int i=0;
        while (const int z = a[i++]
                )
                ;
}