1
1

mca_base_var: fix possibilty of unaligned variable assignments

Add a debugging check that ensures that the registered storage is
aligned appropriately for the type that is specified.

When we know that the storage is properly aligned, we can cast the
mbv_storage to the appropriate type and then simply do the assignment.
We used to do this assignment via a union, but clang's
-fsanitizer=alignment complained about this.

This commit was SVN r32716.
Этот коммит содержится в:
Jeff Squyres 2014-09-11 23:02:49 +00:00
родитель 1f2c5863f0
Коммит d244b7b860

Просмотреть файл

@ -10,7 +10,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2008-2013 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2014 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2012-2014 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2014 Intel, Inc. All rights reserved.
@ -661,15 +661,20 @@ static int var_set_from_string (mca_base_var_t *var, char *src)
if (MCA_BASE_VAR_TYPE_INT == var->mbv_type ||
MCA_BASE_VAR_TYPE_UNSIGNED_INT == var->mbv_type) {
dst->intval = (int) int_value;
int *castme = (int*) var->mbv_storage;
*castme = int_value;
} else if (MCA_BASE_VAR_TYPE_UNSIGNED_LONG == var->mbv_type) {
dst->ulval = (unsigned long) int_value;
unsigned long *castme = (unsigned long*) var->mbv_storage;
*castme = (unsigned long) int_value;
} else if (MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG == var->mbv_type) {
dst->ullval = (unsigned long long) int_value;
unsigned long long *castme = (unsigned long long*) var->mbv_storage;
*castme = (unsigned long long) int_value;
} else if (MCA_BASE_VAR_TYPE_SIZE_T == var->mbv_type) {
dst->sizetval = (size_t) int_value;
size_t *castme = (size_t*) var->mbv_storage;
*castme = (size_t) int_value;
} else if (MCA_BASE_VAR_TYPE_BOOL == var->mbv_type) {
dst->boolval = !!int_value;
bool *castme = (bool*) var->mbv_storage;
*castme = !!int_value;
}
return ret;
@ -1205,6 +1210,43 @@ static int register_variable (const char *project_name, const char *framework_na
/* Developer error. Storage can not be NULL and type must exist */
assert (((flags & MCA_BASE_VAR_FLAG_SYNONYM) || NULL != storage) && type >= 0 && type < MCA_BASE_VAR_TYPE_MAX);
#if OPAL_ENABLE_DEBUG
/* Developer error: check for alignments */
uintptr_t align = 0;
switch (type) {
case MCA_BASE_VAR_TYPE_INT:
align = OPAL_ALIGNMENT_INT;
break;
case MCA_BASE_VAR_TYPE_UNSIGNED_INT:
align = OPAL_ALIGNMENT_INT;
break;
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG:
align = OPAL_ALIGNMENT_LONG;
break;
case MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG:
align = OPAL_ALIGNMENT_LONG_LONG;
break;
case MCA_BASE_VAR_TYPE_SIZE_T:
align = OPAL_ALIGNMENT_SIZE_T;
break;
case MCA_BASE_VAR_TYPE_BOOL:
align = OPAL_ALIGNMENT_BOOL;
break;
case MCA_BASE_VAR_TYPE_DOUBLE:
align = OPAL_ALIGNMENT_DOUBLE;
break;
case MCA_BASE_VAR_TYPE_VERSION_STRING:
case MCA_BASE_VAR_TYPE_STRING:
default:
align = 0;
break;
}
if (0 != align) {
assert(((uintptr_t) storage) % align == 0);
}
#endif
/* There are data holes in the var struct */
OPAL_DEBUG_ZERO(var);