Fix many asan and ubsan reported issues

This allows most demos to run without any ubsan or asan errors. There
are still some things in thirdpart/ and some things in AudioServer that
needs a look but this fixes a lot of issues. This should help debug less
obvious issues, hopefully.

This fixes #25217 and fixes #25218
This commit is contained in:
Hein-Pieter van Braam 2019-01-30 02:12:41 +01:00
parent 35bb52011a
commit d308eb091a
16 changed files with 198 additions and 131 deletions

View File

@ -37,7 +37,11 @@ struct Pair {
F first;
S second;
Pair() {}
Pair() :
first(),
second() {
}
Pair(F p_first, const S &p_second) :
first(p_first),
second(p_second) {

View File

@ -2816,27 +2816,37 @@ uint32_t Variant::hash() const {
const PoolVector<uint8_t> &arr = *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
int len = arr.size();
PoolVector<uint8_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len);
if (likely(len)) {
PoolVector<uint8_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len);
} else {
return hash_djb2_one_64(0);
}
} break;
case POOL_INT_ARRAY: {
const PoolVector<int> &arr = *reinterpret_cast<const PoolVector<int> *>(_data._mem);
int len = arr.size();
PoolVector<int>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
if (likely(len)) {
PoolVector<int>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
} else {
return hash_djb2_one_64(0);
}
} break;
case POOL_REAL_ARRAY: {
const PoolVector<real_t> &arr = *reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
int len = arr.size();
PoolVector<real_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
if (likely(len)) {
PoolVector<real_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
} else {
return hash_djb2_one_float(0.0);
}
} break;
case POOL_STRING_ARRAY: {
@ -2844,10 +2854,13 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
const PoolVector<String> &arr = *reinterpret_cast<const PoolVector<String> *>(_data._mem);
int len = arr.size();
PoolVector<String>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_32(r[i].hash(), hash);
if (likely(len)) {
PoolVector<String>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_32(r[i].hash(), hash);
}
}
return hash;
@ -2857,48 +2870,54 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
const PoolVector<Vector2> &arr = *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
int len = arr.size();
PoolVector<Vector2>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
hash = hash_djb2_one_float(r[i].y, hash);
if (likely(len)) {
PoolVector<Vector2>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
hash = hash_djb2_one_float(r[i].y, hash);
}
}
return hash;
} break;
case POOL_VECTOR3_ARRAY: {
uint32_t hash = 5831;
const PoolVector<Vector3> &arr = *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
int len = arr.size();
PoolVector<Vector3>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
hash = hash_djb2_one_float(r[i].y, hash);
hash = hash_djb2_one_float(r[i].z, hash);
if (likely(len)) {
PoolVector<Vector3>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
hash = hash_djb2_one_float(r[i].y, hash);
hash = hash_djb2_one_float(r[i].z, hash);
}
}
return hash;
} break;
case POOL_COLOR_ARRAY: {
uint32_t hash = 5831;
const PoolVector<Color> &arr = *reinterpret_cast<const PoolVector<Color> *>(_data._mem);
int len = arr.size();
PoolVector<Color>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].r, hash);
hash = hash_djb2_one_float(r[i].g, hash);
hash = hash_djb2_one_float(r[i].b, hash);
hash = hash_djb2_one_float(r[i].a, hash);
if (likely(len)) {
PoolVector<Color>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].r, hash);
hash = hash_djb2_one_float(r[i].g, hash);
hash = hash_djb2_one_float(r[i].b, hash);
hash = hash_djb2_one_float(r[i].a, hash);
}
}
return hash;
} break;
default: {}
}

View File

@ -318,7 +318,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
uniform_code += "uniform ";
uniform_code += _prestr(E->get().precission);
uniform_code += _prestr(E->get().precision);
uniform_code += _typestr(E->get().type);
uniform_code += " ";
uniform_code += _mkid(E->key());
@ -344,7 +344,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
StringBuffer<> varying_code;
varying_code += "varying ";
varying_code += _prestr(E->get().precission);
varying_code += _prestr(E->get().precision);
varying_code += _typestr(E->get().type);
varying_code += " ";
varying_code += _mkid(E->key());

View File

@ -373,7 +373,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
ucode = "uniform ";
}
ucode += _prestr(E->get().precission);
ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type);
ucode += " " + _mkid(E->key());
ucode += ";\n";
@ -464,7 +464,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
String vcode;
String interp_mode = _interpstr(E->get().interpolation);
vcode += _prestr(E->get().precission);
vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + _mkid(E->key());
vcode += ";\n";

View File

@ -110,7 +110,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
String ucode = "uniform ";
ucode += _prestr(E->get().precission);
ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type);
ucode += " " + String(E->key());
@ -137,7 +137,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
String vcode = "varying ";
vcode += _prestr(E->get().precission);
vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + String(E->key());

View File

@ -69,8 +69,12 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s
CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(),
type(p_type),
instance_id(0),
collisionLayer(0),
collisionMask(0),
collisionsEnabled(true),
m_isStatic(false),
ray_pickable(false),
bt_collision_object(NULL),
body_scale(1., 1., 1.),
force_shape_reset(false),

View File

@ -615,6 +615,9 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_
ci.type.script_type = p_gdtype.script_type;
switch (p_gdtype.kind) {
case GDScriptDataType::UNINITIALIZED: {
ERR_EXPLAIN("Uninitialized completion. Please report a bug.");
} break;
case GDScriptDataType::BUILTIN: {
ci.type.kind = GDScriptParser::DataType::BUILTIN;
} break;

View File

@ -45,10 +45,11 @@ class GDScript;
struct GDScriptDataType {
bool has_type;
enum {
UNINITIALIZED,
BUILTIN,
NATIVE,
SCRIPT,
GDSCRIPT
GDSCRIPT,
} kind;
Variant::Type builtin_type;
StringName native_type;
@ -58,6 +59,8 @@ struct GDScriptDataType {
if (!has_type) return true; // Can't type check
switch (kind) {
case UNINITIALIZED:
break;
case BUILTIN: {
Variant::Type var_type = p_variant.get_type();
bool valid = builtin_type == var_type;
@ -113,6 +116,8 @@ struct GDScriptDataType {
PropertyInfo info;
if (has_type) {
switch (kind) {
case UNINITIALIZED:
break;
case BUILTIN: {
info.type = builtin_type;
} break;
@ -134,7 +139,9 @@ struct GDScriptDataType {
}
GDScriptDataType() :
has_type(false) {}
has_type(false),
kind(UNINITIALIZED),
builtin_type(Variant::NIL) {}
};
class GDScriptFunction {

View File

@ -4553,6 +4553,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//variale declaration and (eventual) initialization
ClassNode::Member member;
bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT;
if (current_export.type != Variant::NIL) {
member._export = current_export;
@ -5594,6 +5595,9 @@ GDScriptParser::DataType GDScriptParser::_type_from_gdtype(const GDScriptDataTyp
result.script_type = p_gdtype.script_type;
switch (p_gdtype.kind) {
case GDScriptDataType::UNINITIALIZED: {
ERR_EXPLAIN("Uninitialized datatype. Please report a bug.");
} break;
case GDScriptDataType::BUILTIN: {
result.kind = DataType::BUILTIN;
} break;

View File

@ -95,6 +95,7 @@ public:
}
DataType() :
kind(UNRESOLVED),
has_type(false),
is_constant(false),
is_meta_type(false),
@ -168,6 +169,7 @@ public:
MultiplayerAPI::RPCMode rpc_mode;
int usages;
};
struct Constant {
Node *expression;
DataType type;

View File

@ -3004,7 +3004,9 @@ bool OS_X11::is_vsync_enabled() const {
*/
void OS_X11::set_context(int p_context) {
char *config_name = NULL;
XClassHint *classHint = XAllocClassHint();
if (classHint) {
char *wm_class = (char *)"Godot";
@ -3015,13 +3017,15 @@ void OS_X11::set_context(int p_context) {
if (p_context == CONTEXT_ENGINE) {
classHint->res_name = (char *)"Godot_Engine";
wm_class = (char *)((String)GLOBAL_GET("application/config/name")).utf8().ptrw();
config_name = strdup((char *)((String)GLOBAL_GET("application/config/name")).utf8().ptrw());
wm_class = config_name;
}
classHint->res_class = wm_class;
XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint);
free(config_name);
}
}

View File

@ -114,10 +114,12 @@ private:
Variant value_accum;
uint64_t accum_pass;
Variant capture;
PropertyAnim() {
accum_pass = 0;
object = NULL;
}
PropertyAnim() :
owner(NULL),
special(SP_NONE),
object(NULL),
accum_pass(0) {}
};
Map<StringName, PropertyAnim> property_anim;
@ -129,25 +131,28 @@ private:
float bezier_accum;
Object *object;
uint64_t accum_pass;
BezierAnim() {
accum_pass = 0;
bezier_accum = 0;
object = NULL;
}
BezierAnim() :
owner(NULL),
bezier_accum(0.0),
object(NULL),
accum_pass(0) {}
};
Map<StringName, BezierAnim> bezier_anim;
TrackNodeCache() {
skeleton = NULL;
spatial = NULL;
node = NULL;
accum_pass = 0;
bone_idx = -1;
node_2d = NULL;
audio_playing = false;
animation_playing = false;
}
TrackNodeCache() :
id(0),
node(NULL),
spatial(NULL),
node_2d(NULL),
skeleton(NULL),
bone_idx(-1),
accum_pass(0),
audio_playing(false),
audio_start(0.0),
audio_len(0.0),
animation_playing(false) {}
};
struct TrackNodeCacheKey {

View File

@ -109,6 +109,14 @@ private:
Variant value;
bool skip;
Track() :
id(0),
object(NULL),
spatial(NULL),
skeleton(NULL),
bone_idx(-1),
skip(false) {}
};
typedef Map<TrackKey, Track> TrackMap;

View File

@ -1291,7 +1291,14 @@ void Environment::_bind_methods() {
BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH);
}
Environment::Environment() {
Environment::Environment() :
bg_mode(BG_CLEAR_COLOR),
tone_mapper(TONE_MAPPER_LINEAR),
ssao_blur(SSAO_BLUR_DISABLED),
ssao_quality(SSAO_QUALITY_LOW),
glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE),
dof_blur_far_quality(DOF_BLUR_QUALITY_LOW),
dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) {
environment = VS::get_singleton()->environment_create();

View File

@ -4113,7 +4113,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform.order = uniforms++;
}
uniform.type = type;
uniform.precission = precision;
uniform.precision = precision;
//todo parse default value
@ -4264,7 +4264,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ShaderNode::Varying varying;
varying.type = type;
varying.precission = precision;
varying.precision = precision;
varying.interpolation = interpolation;
shader->varyings[name] = varying;

View File

@ -42,7 +42,6 @@ class ShaderLanguage {
public:
enum TokenType {
TK_EMPTY,
TK_IDENTIFIER,
TK_TRUE,
@ -267,18 +266,15 @@ public:
FLOW_OP_SWITCH,
FLOW_OP_CONTINUE,
FLOW_OP_DISCARD
};
enum ArgumentQualifier {
ARGUMENT_QUALIFIER_IN,
ARGUMENT_QUALIFIER_OUT,
ARGUMENT_QUALIFIER_INOUT,
};
struct Node {
Node *next;
enum Type {
@ -296,7 +292,9 @@ public:
Type type;
virtual DataType get_datatype() const { return TYPE_VOID; }
Node(Type t) :
next(NULL),
type(t) {}
virtual ~Node() {}
};
@ -311,18 +309,17 @@ public:
Node *nodes;
struct OperatorNode : public Node {
DataType return_cache;
DataPrecision return_precision_cache;
Operator op;
Vector<Node *> arguments;
virtual DataType get_datatype() const { return return_cache; }
OperatorNode() {
type = TYPE_OPERATOR;
return_cache = TYPE_VOID;
return_precision_cache = PRECISION_DEFAULT;
}
OperatorNode() :
Node(TYPE_OPERATOR),
return_cache(TYPE_VOID),
return_precision_cache(PRECISION_DEFAULT),
op(OP_EQUAL) {}
};
struct VariableNode : public Node {
@ -330,20 +327,16 @@ public:
StringName name;
virtual DataType get_datatype() const { return datatype_cache; }
VariableNode() {
type = TYPE_VARIABLE;
datatype_cache = TYPE_VOID;
}
VariableNode() :
Node(TYPE_VARIABLE),
datatype_cache(TYPE_VOID) {}
};
struct VariableDeclarationNode : public Node {
DataPrecision precision;
DataType datatype;
struct Declaration {
StringName name;
Node *initializer;
};
@ -351,13 +344,13 @@ public:
Vector<Declaration> declarations;
virtual DataType get_datatype() const { return datatype; }
VariableDeclarationNode() {
type = TYPE_VARIABLE_DECLARATION;
}
VariableDeclarationNode() :
Node(TYPE_VARIABLE_DECLARATION),
precision(PRECISION_DEFAULT),
datatype(TYPE_VOID) {}
};
struct ConstantNode : public Node {
DataType datatype;
union Value {
@ -370,7 +363,9 @@ public:
Vector<Value> values;
virtual DataType get_datatype() const { return datatype; }
ConstantNode() { type = TYPE_CONSTANT; }
ConstantNode() :
Node(TYPE_CONSTANT),
datatype(TYPE_VOID) {}
};
struct FunctionNode;
@ -388,39 +383,41 @@ public:
Map<StringName, Variable> variables;
List<Node *> statements;
bool single_statement;
BlockNode() {
type = TYPE_BLOCK;
parent_block = NULL;
parent_function = NULL;
single_statement = false;
}
BlockNode() :
Node(TYPE_BLOCK),
parent_function(NULL),
parent_block(NULL),
single_statement(false) {}
};
struct ControlFlowNode : public Node {
FlowOperation flow_op;
Vector<Node *> expressions;
Vector<BlockNode *> blocks;
ControlFlowNode() {
type = TYPE_CONTROL_FLOW;
flow_op = FLOW_OP_IF;
}
ControlFlowNode() :
Node(TYPE_CONTROL_FLOW),
flow_op(FLOW_OP_IF) {}
};
struct MemberNode : public Node {
DataType basetype;
DataType datatype;
StringName name;
Node *owner;
virtual DataType get_datatype() const { return datatype; }
MemberNode() { type = TYPE_MEMBER; }
MemberNode() :
Node(TYPE_MEMBER),
basetype(TYPE_VOID),
datatype(TYPE_VOID),
owner(NULL) {}
};
struct FunctionNode : public Node {
struct Argument {
ArgumentQualifier qualifier;
StringName name;
DataType type;
@ -434,16 +431,15 @@ public:
BlockNode *body;
bool can_discard;
FunctionNode() {
type = TYPE_FUNCTION;
return_type = TYPE_VOID;
return_precision = PRECISION_DEFAULT;
can_discard = false;
}
FunctionNode() :
Node(TYPE_FUNCTION),
return_type(TYPE_VOID),
return_precision(PRECISION_DEFAULT),
body(NULL),
can_discard(false) {}
};
struct ShaderNode : public Node {
struct Function {
StringName name;
FunctionNode *function;
@ -454,7 +450,12 @@ public:
struct Varying {
DataType type;
DataInterpolation interpolation;
DataPrecision precission;
DataPrecision precision;
Varying() :
type(TYPE_VOID),
interpolation(INTERPOLATION_FLAT),
precision(PRECISION_DEFAULT) {}
};
struct Uniform {
@ -474,16 +475,20 @@ public:
int order;
int texture_order;
DataType type;
DataPrecision precission;
DataPrecision precision;
Vector<ConstantNode::Value> default_value;
Hint hint;
float hint_range[3];
Uniform() {
hint = HINT_NONE;
hint_range[0] = 0;
hint_range[1] = 1;
hint_range[2] = 0.001;
Uniform() :
order(0),
texture_order(0),
type(TYPE_VOID),
precision(PRECISION_DEFAULT),
hint(HINT_NONE) {
hint_range[0] = 0.0f;
hint_range[1] = 1.0f;
hint_range[2] = 0.001f;
}
};
@ -493,11 +498,11 @@ public:
Vector<Function> functions;
ShaderNode() { type = TYPE_SHADER; }
ShaderNode() :
Node(TYPE_SHADER) {}
};
struct Expression {
bool is_op;
union {
Operator op;
@ -506,7 +511,6 @@ public:
};
struct VarInfo {
StringName name;
DataType type;
};
@ -522,7 +526,6 @@ public:
};
struct Token {
TokenType type;
StringName text;
double constant;
@ -556,11 +559,14 @@ public:
struct BuiltInInfo {
DataType type;
bool constant;
BuiltInInfo() {}
BuiltInInfo(DataType p_type, bool p_constant = false) {
type = p_type;
constant = p_constant;
}
BuiltInInfo() :
type(TYPE_VOID),
constant(false) {}
BuiltInInfo(DataType p_type, bool p_constant = false) :
type(p_type),
constant(p_constant) {}
};
struct FunctionInfo {
@ -573,6 +579,7 @@ private:
TokenType token;
const char *text;
};
static const KeyWord keyword_list[];
bool error_set;
@ -628,14 +635,11 @@ private:
};
bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL);
bool _is_operator_assign(Operator p_op) const;
bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL);
bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL);
struct BuiltinFuncDef {
enum { MAX_ARGS = 5 };
const char *name;
DataType rettype;
@ -643,7 +647,6 @@ private:
};
struct BuiltinFuncOutArgs { //arguments used as out in built in funcions
const char *name;
int argument;
};
@ -656,20 +659,17 @@ private:
int completion_argument;
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
static const BuiltinFuncDef builtin_func_defs[];
static const BuiltinFuncOutArgs builtin_func_out_args[];
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL);
Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
public: