Frama-C: Get slice for C assert statement - frama-c

Is there a way to use Frama-C's slicing plugin to compute slices for a specific C assert statement?
For example, given the following code:
int main() {
double a=3;
double b=4;
double c=123;
assert(b>=0);
double d=a/b;
c=a;
return 0;
}
I would like to get the following slice for assert(b>=0);:
int main() {
double b=4;
assert(b>=0);
return 0;
}

If you can rewrite your assert as an ACSL assertion, you can use option -slice-assert main.
int main() {
double a=3;
double b=4;
double c=123;
//# assert(b>=0);
double d=a/b;
c=a;
return 0;
}
(In this case, the division will also be removed, as it does not influence the assertion.)
void main(void)
{
double b;
b = (double)4;
/*# assert b ≥ 0; */ ;
return;
}
Alternatively, you can also slice on the calls to the assert function, using -slice-calls assert.
void main(void)
{
double b;
b = (double)4;
assert(b >= (double)0);
return;
}
If you want to slice on a particular assertion (if there are more than one in the function), you will have to use a slicing pragma, or the programmatic API (not recommended).

Related

OpenCL sum `cl_khr_fp64` double values into a single number

From this question and this question I managed to compile a minimal example of summing a vector into a single double inside OpenCL 1.2.
/* https://suhorukov.blogspot.com/2011/12/opencl-11-atomic-operations-on-floating.html */
inline void AtomicAdd(volatile __global double *source, const double operand) {
union { unsigned int intVal; double floatVal; } prevVal, newVal;
do {
prevVal.floatVal = *source;
newVal.floatVal = prevVal.floatVal + operand;
} while( atomic_cmpxchg((volatile __global unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal );
}
void kernel cost_function(__constant double* inputs, __global double* outputs){
int index = get_global_id(0);
if(0 == error_index){ outputs[0] = 0.0; }
barrier(CLK_GLOBAL_MEM_FENCE);
AtomicAdd(&outputs[0], inputs[index]); /* (1) */
//AtomicAdd(&outputs[0], 5.0); /* (2) */
}
As in fact this solution is incorrect because the result is always 0 when the buffer is accessed. What might the problem with this?
the code at /* (1) */ doesn't work, and neither does the code at /* (2) */, which is only there to test the logic independent of any inputs.
Is barrier(CLK_GLOBAL_MEM_FENCE); used correctly here to reset the output before any calculations are done to it?
According to the specs in OpenCL 1.2 single precision floating point numbers are supported by atomic operations, is this(AtomicAdd) a feasible method of extending the support to double precision numbers or am I missing something?
Of course the device I am testing with supports cl_khr_fp64˙of course.
Your AtomicAdd is incorrect. Namely, the 2 errors are:
In the union, intVal must be a 64-bit integer and not 32-bit integer.
Use the 64-bit atom_cmpxchg function and not the 32-bit atomic_cmpxchg function.
The correct implementation is:
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
inline void AtomicAdd(volatile __global double *source, const double operand) {
union { unsigned ulong u64; double f64; } prevVal, newVal;
do {
prevVal.f64 = *source;
newVal.f64 = prevVal.f64 + operand;
} while(atom_cmpxchg((volatile __global ulong*)source, prevVal.u64, newVal.u64) != prevVal.u64);
}
barrier(CLK_GLOBAL_MEM_FENCE); is used correctly here. Note that a barrier must not be in an if- or else-branch.
UPDATE: According to STREAMHPC, the original implementation you use is not guaranteed to produce correct results. There is an improved implementation:
void __attribute__((always_inline)) atomic_add_f(volatile global float* addr, const float val) {
union {
uint u32;
float f32;
} next, expected, current;
current.f32 = *addr;
do {
next.f32 = (expected.f32=current.f32)+val; // ...*val for atomic_mul_f()
current.u32 = atomic_cmpxchg((volatile global uint*)addr, expected.u32, next.u32);
} while(current.u32!=expected.u32);
}
#ifdef cl_khr_int64_base_atomics
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
void __attribute__((always_inline)) atomic_add_d(volatile global double* addr, const double val) {
union {
ulong u64;
double f64;
} next, expected, current;
current.f64 = *addr;
do {
next.f64 = (expected.f64=current.f64)+val; // ...*val for atomic_mul_d()
current.u64 = atom_cmpxchg((volatile global ulong*)addr, expected.u64, next.u64);
} while(current.u64!=expected.u64);
}
#endif

Correct Assignment for Pointers

I am shifting from Python to C so bit rusty on the semantics as well as coding habit. In Python everything is treated as an object and objects are passed to functions. This is not the case in C so I want to increment an integer using pointers. What is the correct assignment to do so. I want to do it the following way but have the assignments wrong:
#include <stdio.h>
int i = 24;
int increment(*i){
*i++;
return i;
}
int main() {
increment(&i);
printf("i = %d, i);
return 0;
}
I fixed your program:
#include <stdio.h>
int i = 24;
// changed from i to j in order to avoid confusion.
// note you could declare the return type as void instead
int increment(int *j){
(*j)++;
return *j;
}
int main() {
increment(&i);
printf("i = %d", i);
return 0;
}
Your main error was the missing int in the function's argument (also a missing " in the printf).
Also I would prefer using parentheses in expressions as *j++ and specify exactly the precedence like I did in (*j)++, because I want to increment the content of the variable in the 'j' location not to increment the pointer - meaning to point it on the next memory cell - and then use its content.

How to properly use qRegisterMetaType with multidimensional arrays?

I want to use something like
typedef double Matrix[4][4];
to represent transformations and also pass them around with the QT signal/slot mechanism. But when I use
Q_DECLARE_METATYPE(Matrix)
it throws an error in qmetatype.h at this function
void *qMetaTypeConstructHelper(const T *t)
{
if (!t)
return new T();
return new T(*static_cast<const T*>(t));
}
saying: "error C2075: 'Target of operator new()' : array initialization needs curly braces"
Q_DECLARE_METATYPE(T) requires the type T to be default-constructable, copiable and destructable. Your Matrix type is not copiable, thus you can't use Q_DECLARE_METATYPE on it.
Workaround: use a class.
// copiable, C++98 brace-initializable, etc.
struct Matrix {
double data[4][4];
};
Ideally you should be using eigen3 and its types. Alternatively, wrap your type in a class. Once you do it, you might as well have the class do more than be a mere wrapper. Eventually, you'll see that eigen3 is the only sane way to proceed. Probably when you get to this point:
#include <cstring>
class Matrix {
double m_data[4][4];
public:
typedef double (*Data)[4];
Matrix() {}
Matrix(const Matrix & other) { memcpy(m_data, other.m_data, sizeof m_data); }
Matrix & operator=(const Matrix & other) { memcpy(m_data, other.m_data, sizeof m_data); return *this; }
Matrix & operator=(const Data other) { memcpy(m_data, other, sizeof m_data); return *this; }
operator Data() { return m_data; }
};
int main()
{
double mat1[4][4];
Matrix mat2;
mat2[3][3] = 1;
mat2 = mat1;
return 0;
}

Program fails when trying to add a pointer to an array inside a function (C)

I cannot get this code to work properly. When I try to compile it, one of three things will happen: Either I'll get no errors, but when I run the program, it immediately locks up; or it'll compile fine, but says 'Segmentation fault' and exits when I run it; or it gives warnings when compiled:
"conflicting types for ‘addObjToTree’
previous implicit declaration of ‘addObjToTree’ was here"
but then says 'Segmentation fault' and exits when I try to run it.
I'm on Mac OS X 10.6 using gcc.
game-obj.h:
typedef struct itemPos {
float x;
float y;
} itemPos;
typedef struct gameObject {
itemPos loc;
int uid;
int kind;
int isEmpty;
...
} gameObject;
internal-routines.h:
void addObjToTree (gameObject *targetObj, gameObject *destTree[]) {
int i = 0;
int stop = 1;
while (stop) {
if ((*destTree[i]).isEmpty == 0)
i++;
else if ((*destTree[i]).isEmpty == 1)
stop = 0;
else
;/*ERROR*/
}
if (stop == 0) {
destTree[i] = targetObj;
}
else
{
;/*ERROR*/
}
}
/**/
void initFS_LA (gameObject *target, gameObject *tree[], itemPos destination) {
addObjToTree(target, tree);
(*target).uid = 12981;
(*target).kind = 101;
(*target).isEmpty = 0;
(*target).maxHealth = 100;
(*target).absMaxHealth = 200;
(*target).curHealth = 100;
(*target).skill = 1;
(*target).isSolid = 1;
(*target).factionID = 555;
(*target).loc.x = destination.x;
(*target).loc.y = destination.y;
}
main.c:
#include "game-obj.h"
#include "internal-routines.h"
#include <stdio.h>
int main()
{
gameObject abc;
gameObject jkl;
abc.kind = 101;
abc.uid = 1000;
itemPos aloc;
aloc.x = 10;
aloc.y = 15;
gameObject *masterTree[3];
masterTree[0] = &(abc);
initFS_LA(&jkl, masterTree, aloc);
printf("%d\n",jkl.factionID);
return 0;
}
I don't understand why it doesn't work. I just want addObjToTree(...) to add a pointer to a gameObject in the next free space of masterTree, which is an array of pointers to gameObject structures. even weirder, if I remove the line addObjToTree(target, tree); from initFS_LA(...) it works perfectly. I've already created a function that searches masterTree by uid and that also works fine, even if I initialize a new gameObject with initFS_LA(...) (without the addObjToTree line.) I've tried rearranging the functions within the header file, putting them into separate header files, prototyping them, rearranging the order of #includes, explicitly creating a pointer variable instead of using &jkl, but absolutely nothing works. Any ideas? I appreciate any help
If I see this correctly, then you don't initialize elements 1 and 2 of the masterTree array anywhere. Then, your addObjToTree() function searches the - uninitialized - array for a free element.
Declaring a variable like gameObject *masterTree[3]; in C does not zero-initialize the array. Add some memset (masterTree, 0, sizeof (masterTree)); to initialize.
Note that you're declaring an array of pointers to structs here, not an array of structs (see also here), so you also need to adjust your addObjToTree() to check for a NULL-pointer instead of isEmpty.
It would also be good practice to pass the length of that array to that function to avoid buffer overruns.
If you want an array of structs, then you need to declare it as gameObject masterTree[3]; and the parameter in your addObjToTree() becomes gameObject *tree.

c++0x: Variadic Template technique

I am preparing myself for the defintion of user-defined literals with a Variadic Template
template<...>
unsigned operator "" _binary();
unsigned thirteen = 1101_binary;
GCC 4.7.0 does not support operator "" yet, but I can simulate this with a simple function until then.
Alas, my recursion is the wrong way around. I can not think of a nice way how I do not shift the rightmost values, but the leftmost:
template<char C> int _bin();
template<> int _bin<'1'>() { return 1; }
template<> int _bin<'0'>() { return 0; }
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() | _bin<D,ES...>() << 1; // <-- WRONG!
}
which of course is not quite right:
int val13 = _bin<'1','1','0','1'>(); // <-- gives 10
because my recursion shifts the rightmost '1's farthest, and not the leftmost ones.
It is probably I tiny thing, but I just can not see it.
Can I correct the line _bin<C>() | _bin<D,ES...>() << 1;?
Or do I have to forward everything and turn it around everything afterwards (not nice)?
Or any other way that I can not see?
Update: I could not fold the recursion the other way around, but I discovered sizeof.... Works, but not perfect. Is there another way?
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() << (sizeof...(ES)+1) | _bin<D,ES...>() ;
}
At any one step of the recursion you already know the rank of the leftmost digit.
template<char C> int _bin();
template<> int _bin<'1'>() { return 1; }
template<> int _bin<'0'>() { return 0; }
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() << (1 + sizeof...(ES)) | _bin<D,ES...>();
}
Parameter packs are relatively inflexible, and you don't usually write algorithms directly in them. Variadic function templates are good for forwarding, but I'd get that packed into a more manageable tuple before trying to manipulate it.
Using a simple binary_string_value metafunction where the 1's place comes first, and a generic tuple_reverse metafunction, the pattern would be
template< char ... digit_pack >
constexpr unsigned long long _bin() {
typedef std::tuple< std::integral_constant< digit_pack - '0' > ... > digit_tuple;
return binary_string_value< typename tuple_reverse< digit_tuple >::type >::value;
}
One possibility would be using an accumulator:
template <char C>
int _binchar();
template<>
int _binchar<'0'>() { return 0; }
template<>
int _binchar<'1'>() { return 1; }
template<char C>
int _bin(int acc=0) {
return (acc*2 + _binchar<C>());
}
template<char C, char D, char... ES>
int _bin(int acc=0) {
return _bin<D, ES...>(acc*2 + _binchar<C>());
}

Resources