Skip to content

Commit 8ccb377

Browse files
author
Daniel Kroening
committed
introduce gcc_asm_gcct
This will prevent direct accesses to operands of codet.
1 parent 727f7e6 commit 8ccb377

File tree

5 files changed

+118
-25
lines changed

5 files changed

+118
-25
lines changed

src/ansi-c/c_typecheck_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class c_typecheck_baset:
124124
virtual void typecheck_code(codet &code);
125125

126126
virtual void typecheck_assign(codet &expr);
127-
virtual void typecheck_asm(codet &code);
127+
virtual void typecheck_asm(code_asmt &code);
128128
virtual void typecheck_block(code_blockt &code);
129129
virtual void typecheck_break(codet &code);
130130
virtual void typecheck_continue(codet &code);

src/ansi-c/c_typecheck_code.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void c_typecheck_baset::typecheck_code(codet &code)
7676
{
7777
}
7878
else if(statement==ID_asm)
79-
typecheck_asm(code);
79+
typecheck_asm(to_code_asm(code));
8080
else if(statement==ID_start_thread)
8181
typecheck_start_thread(code);
8282
else if(statement==ID_gcc_local_label)
@@ -133,28 +133,28 @@ void c_typecheck_baset::typecheck_code(codet &code)
133133
}
134134
}
135135

136-
void c_typecheck_baset::typecheck_asm(codet &code)
136+
void c_typecheck_baset::typecheck_asm(code_asmt &code)
137137
{
138-
const irep_idt flavor=to_code_asm(code).get_flavor();
138+
const irep_idt flavor = code.get_flavor();
139139

140140
if(flavor==ID_gcc)
141141
{
142142
// These have 5 operands.
143-
// The first parameter is a string.
144-
// Parameters 1, 2, 3, 4 are lists of expressions.
143+
// The first operand is a string.
144+
// Operands 1, 2, 3, 4 are lists of expressions.
145145

146-
// Parameter 1: OutputOperands
147-
// Parameter 2: InputOperands
148-
// Parameter 3: Clobbers
149-
// Parameter 4: GotoLabels
146+
// Operand 1: OutputOperands
147+
// Operand 2: InputOperands
148+
// Operand 3: Clobbers
149+
// Operand 4: GotoLabels
150150

151-
assert(code.operands().size()==5);
151+
auto &code_asm_gcc = to_code_asm_gcc(code);
152152

153-
typecheck_expr(code.op0());
153+
typecheck_expr(code_asm_gcc.asm_text());
154154

155-
for(std::size_t i=1; i<code.operands().size(); i++)
155+
for(std::size_t i = 1; i < code_asm_gcc.operands().size(); i++)
156156
{
157-
exprt &list=code.operands()[i];
157+
exprt &list = code_asm_gcc.operands()[i];
158158
Forall_operands(it, list)
159159
typecheck_expr(*it);
160160
}

src/assembler/remove_asm.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ class remove_asmt
4747
goto_programt::instructiont &instruction,
4848
goto_programt &dest);
4949

50-
void process_instruction_gcc(const code_asmt &, goto_programt &dest);
50+
void process_instruction_gcc(const code_asm_gcct &, goto_programt &dest);
5151

5252
void process_instruction_msc(const code_asmt &, goto_programt &dest);
5353

5454
void gcc_asm_function_call(
5555
const irep_idt &function_base_name,
56-
const code_asmt &code,
56+
const code_asm_gcct &code,
5757
goto_programt &dest);
5858

5959
void msc_asm_function_call(
@@ -71,7 +71,7 @@ class remove_asmt
7171
/// \param dest: Goto program to append the function call to
7272
void remove_asmt::gcc_asm_function_call(
7373
const irep_idt &function_base_name,
74-
const code_asmt &code,
74+
const code_asm_gcct &code,
7575
goto_programt &dest)
7676
{
7777
irep_idt function_identifier = function_base_name;
@@ -81,7 +81,7 @@ void remove_asmt::gcc_asm_function_call(
8181
const typet void_pointer = pointer_type(empty_typet());
8282

8383
// outputs
84-
forall_operands(it, code.op1())
84+
forall_operands(it, code.outputs())
8585
{
8686
if(it->operands().size() == 2)
8787
{
@@ -91,7 +91,7 @@ void remove_asmt::gcc_asm_function_call(
9191
}
9292

9393
// inputs
94-
forall_operands(it, code.op2())
94+
forall_operands(it, code.inputs())
9595
{
9696
if(it->operands().size() == 2)
9797
{
@@ -197,7 +197,7 @@ void remove_asmt::process_instruction(
197197
const irep_idt &flavor = code.get_flavor();
198198

199199
if(flavor == ID_gcc)
200-
process_instruction_gcc(code, dest);
200+
process_instruction_gcc(to_code_asm_gcc(code), dest);
201201
else if(flavor == ID_msc)
202202
process_instruction_msc(code, dest);
203203
else
@@ -210,10 +210,10 @@ void remove_asmt::process_instruction(
210210
/// \param code: The inline assembly code statement to translate
211211
/// \param dest: The goto program to append the new instructions to
212212
void remove_asmt::process_instruction_gcc(
213-
const code_asmt &code,
213+
const code_asm_gcct &code,
214214
goto_programt &dest)
215215
{
216-
const irep_idt &i_str = to_string_constant(code.op0()).get_value();
216+
const irep_idt &i_str = to_string_constant(code.asm_text()).get_value();
217217

218218
std::istringstream str(id2string(i_str));
219219
assembler_parser.clear();

src/cpp/parse.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7920,9 +7920,7 @@ bool Parser::rGCCAsmStatement(codet &statement)
79207920
if(lex.get_token(tk)!=TOK_GCC_ASM)
79217921
return false;
79227922

7923-
statement=codet(ID_asm);
7924-
statement.set(ID_flavor, ID_gcc);
7925-
statement.operands().resize(5); // always has 5 operands
7923+
statement = code_asm_gcct();
79267924
set_location(statement, tk);
79277925

79287926
if(lex.LookAhead(0)==TOK_VOLATILE)

src/util/std_code.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,101 @@ inline const code_asmt &to_code_asm(const codet &code)
16751675
return static_cast<const code_asmt &>(code);
16761676
}
16771677

1678+
/// \ref codet representation of an inline assembler statement,
1679+
/// for the gcc flavor.
1680+
class code_asm_gcct : public code_asmt
1681+
{
1682+
public:
1683+
code_asm_gcct()
1684+
{
1685+
set_flavor(ID_gcc);
1686+
operands().resize(5);
1687+
}
1688+
1689+
exprt &asm_text()
1690+
{
1691+
return op0();
1692+
}
1693+
1694+
const exprt &asm_text() const
1695+
{
1696+
return op0();
1697+
}
1698+
1699+
exprt &outputs()
1700+
{
1701+
return op1();
1702+
}
1703+
1704+
const exprt &outputs() const
1705+
{
1706+
return op1();
1707+
}
1708+
1709+
exprt &inputs()
1710+
{
1711+
return op2();
1712+
}
1713+
1714+
const exprt &inputs() const
1715+
{
1716+
return op2();
1717+
}
1718+
1719+
exprt &clobbers()
1720+
{
1721+
return op3();
1722+
}
1723+
1724+
const exprt &clobbers() const
1725+
{
1726+
return op3();
1727+
}
1728+
1729+
exprt &labels()
1730+
{
1731+
return operands()[4];
1732+
}
1733+
1734+
const exprt &labels() const
1735+
{
1736+
return operands()[4];
1737+
}
1738+
1739+
protected:
1740+
using code_asmt::op0;
1741+
using code_asmt::op1;
1742+
using code_asmt::op2;
1743+
using code_asmt::op3;
1744+
};
1745+
1746+
template <>
1747+
inline bool can_cast_expr<code_asm_gcct>(const exprt &base)
1748+
{
1749+
return detail::can_cast_code_impl(base, ID_asm);
1750+
}
1751+
1752+
// to_code_asm_gcc only checks the code statement, so no validate_expr is
1753+
// provided for code_asmt
1754+
1755+
inline code_asm_gcct &to_code_asm_gcc(codet &code)
1756+
{
1757+
PRECONDITION(code.get_statement() == ID_asm);
1758+
PRECONDITION(to_code_asm(code).get_flavor() == ID_gcc);
1759+
DATA_INVARIANT(
1760+
code.operands().size() == 5, "code_asm_gcc must have give operands");
1761+
return static_cast<code_asm_gcct &>(code);
1762+
}
1763+
1764+
inline const code_asm_gcct &to_code_asm_gcc(const codet &code)
1765+
{
1766+
PRECONDITION(code.get_statement() == ID_asm);
1767+
PRECONDITION(to_code_asm(code).get_flavor() == ID_gcc);
1768+
DATA_INVARIANT(
1769+
code.operands().size() == 5, "code_asm_gcc must have give operands");
1770+
return static_cast<const code_asm_gcct &>(code);
1771+
}
1772+
16781773
/// \ref codet representation of an expression statement.
16791774
/// It has one operand, which is the expression it stores.
16801775
class code_expressiont:public codet

0 commit comments

Comments
 (0)