[libcamera-devel] [PATCH] libcamera: controls: Fix strict aliasing violation

Kieran Bingham kieran.bingham at ideasonboard.com
Sun Mar 8 00:37:21 CET 2020


Hi Laurent,

On 07/03/2020 21:25, Laurent Pinchart wrote:
> gcc 8.3.0 for ARM complains about strict aliasing violations:
> 
> ../../src/libcamera/controls.cpp: In member function ‘void libcamera::ControlValue::release()’:
> ../../src/libcamera/controls.cpp:111:13: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
>    delete[] *reinterpret_cast<char **>(&storage_);
> 
> Fix it and simplify the code at the same time.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

For either kept separate, or squashed into the other patch that adds this:

Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>

Though I wonder, could the above error also have been resolved with use
of a uintptr_t?

But the union does seem to make the duality of use more clear to me all
the same.



> ---
>  include/libcamera/controls.h |  5 ++++-
>  src/libcamera/controls.cpp   | 20 ++++++++++----------
>  2 files changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
> index 4767e2d3fc8c..0e111ab72bce 100644
> --- a/include/libcamera/controls.h
> +++ b/include/libcamera/controls.h
> @@ -160,7 +160,10 @@ private:
>  	ControlType type_ : 8;
>  	bool isArray_ : 1;
>  	std::size_t numElements_ : 16;
> -	uint64_t storage_;
> +	union {
> +		uint64_t value_;
> +		void *storage_;
> +	};
>  
>  	void release();
>  	void set(ControlType type, bool isArray, const void *data,
> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
> index 94bdbdd9c388..4326174adf86 100644
> --- a/src/libcamera/controls.cpp
> +++ b/src/libcamera/controls.cpp
> @@ -107,9 +107,9 @@ void ControlValue::release()
>  {
>  	std::size_t size = numElements_ * ControlValueSize[type_];
>  
> -	if (size > sizeof(storage_)) {
> -		delete[] *reinterpret_cast<char **>(&storage_);
> -		storage_ = 0;
> +	if (size > sizeof(value_)) {
> +		delete[] reinterpret_cast<uint8_t *>(storage_);
> +		storage_ = nullptr;
>  	}
>  }
>  
> @@ -176,9 +176,9 @@ ControlValue &ControlValue::operator=(const ControlValue &other)
>  Span<const uint8_t> ControlValue::data() const
>  {
>  	std::size_t size = numElements_ * ControlValueSize[type_];
> -	const uint8_t *data = size > sizeof(storage_)
> -			    ? *reinterpret_cast<const uint8_t * const *>(&storage_)
> -			    : reinterpret_cast<const uint8_t *>(&storage_);
> +	const uint8_t *data = size > sizeof(value_)
> +			    ? reinterpret_cast<const uint8_t *>(storage_)
> +			    : reinterpret_cast<const uint8_t *>(&value_);
>  	return { data, size };
>  }
>  
> @@ -308,11 +308,11 @@ void ControlValue::set(ControlType type, bool isArray, const void *data,
>  	std::size_t size = elementSize * numElements;
>  	void *storage;
>  
> -	if (size > sizeof(storage_)) {
> -		storage = reinterpret_cast<void *>(new char[size]);
> -		*reinterpret_cast<void **>(&storage_) = storage;
> +	if (size > sizeof(value_)) {
> +		storage_ = reinterpret_cast<void *>(new uint8_t[size]);
> +		storage = storage_;
>  	} else {
> -		storage = reinterpret_cast<void *>(&storage_);
> +		storage = reinterpret_cast<void *>(&value_);
>  	}
>  
>  	memcpy(storage, data, size);
> 

-- 
Regards
--
Kieran


More information about the libcamera-devel mailing list