Index: cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto =================================================================== --- cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto +++ cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto @@ -11,7 +11,7 @@ /// This file describes a subset of C++ as a protobuf. It is used to /// more easily find interesting inputs for fuzzing Clang. This subset /// differs from the one defined in cxx_proto.proto by eliminating while -/// loops and Lvalues. The goal is that the C++ code generated will be +/// loops and conditionals. The goal is that the C++ code generated will be /// more likely to stress the LLVM loop vectorizer. /// //===----------------------------------------------------------------------===// @@ -22,6 +22,16 @@ required int32 val = 1; } +message VarRef { + // Add an enum for each array in function signature + enum Arr { + ARR_A = 0; + ARR_B = 1; + ARR_C = 2; + }; + required Arr arr = 1; +} + message BinaryOp { enum Op { PLUS = 0; @@ -48,10 +58,12 @@ oneof rvalue_oneof { Const cons = 1; BinaryOp binop = 2; + VarRef varref = 3; } } message AssignmentStatement { + required VarRef varref = 1; required Rvalue rvalue = 2; } @@ -62,10 +74,7 @@ } message Statement { - oneof stmt_oneof { - AssignmentStatement assignment = 1; - IfElse ifelse = 2; - } + required AssignmentStatement assignment = 1; } message StatementSeq { Index: cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp =================================================================== --- cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp +++ cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp @@ -36,11 +36,23 @@ std::ostream &operator<<(std::ostream &os, const Const &x) { return os << "(" << x.val() << ")"; } +std::ostream &operator<<(std::ostream &os, const VarRef &x) { + switch (x.arr()) { + case VarRef::ARR_A: + return os << "a[i]"; + case VarRef::ARR_B: + return os << "b[i]"; + case VarRef::ARR_C: + return os << "c[i]"; + } +} std::ostream &operator<<(std::ostream &os, const Rvalue &x) { if (x.has_cons()) return os << x.cons(); if (x.has_binop()) return os << x.binop(); + if (x.has_varref()) + return os << x.varref(); return os << "1"; } std::ostream &operator<<(std::ostream &os, const BinaryOp &x) { @@ -92,7 +104,7 @@ return os << x.right() << ")"; } std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) { - return os << "a[i]=" << x.rvalue(); + return os << x.varref() << "=" << x.rvalue() << ";\n"; } std::ostream &operator<<(std::ostream &os, const IfElse &x) { return os << "if (" << x.cond() << "){\n" @@ -100,11 +112,7 @@ << x.else_body() << "}\n"; } std::ostream &operator<<(std::ostream &os, const Statement &x) { - if (x.has_assignment()) - return os << x.assignment() << ";\n"; - if (x.has_ifelse()) - return os << x.ifelse(); - return os << "(void)0;\n"; + return os << x.assignment(); } std::ostream &operator<<(std::ostream &os, const StatementSeq &x) { for (auto &st : x.statements()) @@ -112,7 +120,7 @@ return os; } std::ostream &operator<<(std::ostream &os, const LoopFunction &x) { - return os << "void foo(int *a, size_t s) {\n" + return os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n" << "for (int i=0; i