You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
4.0 KiB

/*
* Copyright (c) 2016 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// header required by TranslateAsPtr class. It's not in common header search
// path when running clang without infer (clang wrappers add it)
// Add -isystem '/path/models/cpp/include' to clang invocation to work around
// compilation problem
#include <infer_model/infer_traits.h>
/* Test for passing function attributes to infer via __deprecated__ attribute */
// basic test of C function with __infer_replace_with_deref_first_arg attribute
int derefFirstArg(int* a, int* b)
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {
/* equivalent in real code:
return *a; */
}
int derefFirstArg2(int* a, int* b)
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {
/* equivalent in real code:
return *a; */
return *b; // body is in conflict with the attribute, attribute semantics
// should be used
}
int derefFirstArg3(int* a, int* b) __attribute__((deprecated("__infer_typo"))) {
/* equivalent in real code: */
return *b; // there isn't any known attribute with this name, use semantics
// from the body
}
int derefFirstArg_null_deref() {
int a = 0;
return derefFirstArg(nullptr, &a);
}
int derefFirstArg_ok_deref() {
int a = 0;
return derefFirstArg(&a, nullptr);
}
int derefFirstArg2_null_deref() {
int a = 0;
return derefFirstArg2(nullptr, &a);
}
int derefFirstArg2_ok_deref() {
int a = 0;
return derefFirstArg2(&a, nullptr);
}
int derefFirstArg3_ok_deref() {
int a = 0;
return derefFirstArg3(nullptr, &a);
}
int derefFirstArg3_null_deref() {
int a = 0;
return derefFirstArg3(&a, nullptr);
}
// more involving test of __infer_replace_with_deref_first_arg attribute in
// context of C++
// methods
/* This class be translated as T* by infer frontend - same as shared_ptr
This class has different API in order to better test __deprecated__ attribute
handling by the frontend. */
template <class T>
struct TranslateAsPtr {
friend class infer_traits::TranslateAsType<T*>;
TranslateAsPtr(T* t = nullptr) { setPtr(t); }
/* calls to those functions are supposed to be translated as `*this` */
T* getPtr()
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {}
T* getPtr(int a, int b)
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {}
/* calls to those functions are supposed to be translated as `**this` */
T& operator*()
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {}
T& getRef()
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {}
T& getRef(int a, int b)
__attribute__((deprecated("__infer_replace_with_deref_first_arg"))) {}
// same trick we do for setting value of shared_ptr, look there for details
void setPtr(T* v) { *((void**)(this)) = v; }
};
int getPtr_null_deref1() {
TranslateAsPtr<int> t;
t.setPtr(nullptr);
return *t.getPtr();
}
int getPtr_null_deref2() {
TranslateAsPtr<int> t;
t.setPtr(nullptr);
return *t.getPtr(1, 2);
}
int getPtr_ok_deref() {
int a = 0;
TranslateAsPtr<int> t;
t.setPtr(&a);
return *t.getPtr();
}
int operator_star_null_deref1() {
TranslateAsPtr<int> t;
t.setPtr(nullptr);
return *t; // call operator* via operator call
}
int operator_star_null_deref2() {
TranslateAsPtr<int> t;
t.setPtr(nullptr);
return t.operator*(); // call operator* via regular method call
}
int operator_star_ok_deref() {
int a;
TranslateAsPtr<int> t;
t.setPtr(&a);
return t.operator*(); // call operator* via regular method call
}
int getRef_null_deref1() {
TranslateAsPtr<int> t;
t.setPtr(nullptr);
return t.getRef();
}
int getRef_null_deref2() {
TranslateAsPtr<int> t;
t.setPtr(nullptr);
return t.getRef(1, 2);
}
int getRef_ok_deref() {
int a = 0;
TranslateAsPtr<int> t;
t.setPtr(&a);
return t.getRef();
}